12 #define NewCipher(klass) \ 13 TypedData_Wrap_Struct((klass), &ossl_cipher_type, 0) 14 #define AllocCipher(obj, ctx) do { \ 15 (ctx) = EVP_CIPHER_CTX_new(); \ 17 ossl_raise(rb_eRuntimeError, NULL); \ 18 RTYPEDDATA_DATA(obj) = (ctx); \ 20 #define GetCipherInit(obj, ctx) do { \ 21 TypedData_Get_Struct((obj), EVP_CIPHER_CTX, &ossl_cipher_type, (ctx)); \ 23 #define GetCipher(obj, ctx) do { \ 24 GetCipherInit((obj), (ctx)); \ 26 ossl_raise(rb_eRuntimeError, "Cipher not initialized!"); \ 29 #define SafeGetCipher(obj, ctx) do { \ 30 OSSL_Check_Kind((obj), cCipher); \ 31 GetCipher((obj), (ctx)); \ 63 return EVP_CIPHER_CTX_cipher(ctx);
66 const EVP_CIPHER *cipher;
72 "unsupported cipher algorithm: %"PRIsVALUE, obj);
86 if (EVP_CipherInit_ex(ctx, cipher,
NULL,
NULL,
NULL, -1) != 1)
119 const EVP_CIPHER *cipher;
128 if (!(cipher = EVP_get_cipherbyname(name))) {
131 if (EVP_CipherInit_ex(ctx, cipher,
NULL,
NULL,
NULL, -1) != 1)
140 EVP_CIPHER_CTX *ctx1, *ctx2;
143 if (
self == other)
return self;
175 OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH,
207 unsigned char key[EVP_MAX_KEY_LENGTH], *p_key =
NULL;
208 unsigned char iv[EVP_MAX_IV_LENGTH], *p_iv =
NULL;
219 "use %"PRIsVALUE"#pkcs5_keyivgen to derive key and IV",
220 cname, cname, cname);
223 if (
NIL_P(init_v))
memcpy(iv,
"OpenSSL for Ruby rulez!",
sizeof(iv));
227 memset(iv, 0, EVP_MAX_IV_LENGTH);
232 EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), EVP_md5(), iv,
240 if (EVP_CipherInit_ex(ctx,
NULL,
NULL, p_key, p_iv, mode) != 1) {
310 const EVP_MD *digest;
311 VALUE vpass, vsalt, viter, vdigest;
312 unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH], *salt =
NULL;
315 rb_scan_args(argc, argv,
"13", &vpass, &vsalt, &viter, &vdigest);
326 EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), digest, salt,
328 if (EVP_CipherInit_ex(ctx,
NULL,
NULL, key, iv, -1) != 1)
330 OPENSSL_cleanse(key,
sizeof key);
331 OPENSSL_cleanse(iv,
sizeof iv);
340 const unsigned char *in,
long in_len)
343 int limit = INT_MAX / 2 + 1;
347 int in_part_len = in_len > limit ? limit : (int)in_len;
349 if (!EVP_CipherUpdate(ctx, out ? (out + out_len) : 0,
350 &out_part_len, in, in_part_len))
353 out_len += out_part_len;
355 }
while ((in_len -= limit) > 0);
358 *out_len_ptr = out_len;
380 long in_len, out_len;
393 out_len = in_len+EVP_CIPHER_CTX_block_size(ctx);
396 "data too big to make output buffer: %ld bytes", in_len);
436 str =
rb_str_new(0, EVP_CIPHER_CTX_block_size(ctx));
437 if (!EVP_CipherFinal_ex(ctx, (
unsigned char *)
RSTRING_PTR(str), &out_len))
459 return rb_str_new2(EVP_CIPHER_name(EVP_CIPHER_CTX_cipher(ctx)));
482 key_len = EVP_CIPHER_CTX_key_length(ctx);
515 #if defined(HAVE_AUTHENTICATED_ENCRYPTION) 516 if (EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER)
517 iv_len = (int)(
VALUE)EVP_CIPHER_CTX_get_app_data(ctx);
520 iv_len = EVP_CIPHER_CTX_iv_length(ctx);
544 #if defined(HAVE_AUTHENTICATED_ENCRYPTION) 545 return (EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER) ?
Qtrue :
Qfalse;
551 #ifdef HAVE_AUTHENTICATED_ENCRYPTION 575 long in_len, out_len;
615 if (!
NIL_P(vtag_len))
620 if (!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER))
624 if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, tag_len,
RSTRING_PTR(ret)))
657 if (!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER))
660 if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tag_len, tag))
684 if (!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER))
687 if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tag_len,
NULL))
711 if (!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER))
714 if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, len,
NULL))
721 EVP_CIPHER_CTX_set_app_data(ctx, (
void *)(
VALUE)len);
726 #define ossl_cipher_set_auth_data rb_f_notimplement 727 #define ossl_cipher_get_auth_tag rb_f_notimplement 728 #define ossl_cipher_set_auth_tag rb_f_notimplement 729 #define ossl_cipher_set_auth_tag_len rb_f_notimplement 730 #define ossl_cipher_set_iv_length rb_f_notimplement 752 if (EVP_CIPHER_CTX_set_key_length(ctx, len) != 1)
775 if (EVP_CIPHER_CTX_set_padding(ctx, pad) != 1)
793 return INT2NUM(EVP_CIPHER_CTX_key_length(ctx));
809 #if defined(HAVE_AUTHENTICATED_ENCRYPTION) 810 if (EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER)
811 len = (int)(
VALUE)EVP_CIPHER_CTX_get_app_data(ctx);
814 len = EVP_CIPHER_CTX_iv_length(ctx);
832 return INT2NUM(EVP_CIPHER_CTX_block_size(ctx));
static VALUE ossl_s_ciphers(VALUE self)
static const rb_data_type_t ossl_cipher_type
static VALUE ossl_cipher_alloc(VALUE klass)
#define ossl_cipher_set_auth_data
#define EVP_CIPHER_CTX_copy
static VALUE ossl_cipher_final(VALUE self)
#define RUBY_TYPED_FREE_IMMEDIATELY
static VALUE ossl_cipher_init(int argc, VALUE *argv, VALUE self, int mode)
#define AllocCipher(obj, ctx)
#define ossl_cipher_set_iv_length
VALUE rb_ary_push(VALUE ary, VALUE item)
static VALUE ossl_cipher_update(int argc, VALUE *argv, VALUE self)
void rb_str_set_len(VALUE, long)
static void * add_cipher_name_to_ary(const OBJ_NAME *name, VALUE ary)
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
VALUE rb_obj_is_kind_of(VALUE, VALUE)
static VALUE ossl_cipher_block_size(VALUE self)
#define GetCipher(obj, ctx)
#define EVP_CIPHER_CTX_free
static VALUE ossl_cipher_set_key_length(VALUE self, VALUE key_length)
static void ossl_cipher_free(void *ptr)
#define rb_define_copy_func(klass, func)
static VALUE ossl_cipher_initialize(VALUE self, VALUE str)
VALUE ossl_cipher_new(const EVP_CIPHER *cipher)
#define SafeGetCipher(obj, ctx)
RUBY_EXTERN VALUE rb_cObject
#define ossl_cipher_get_auth_tag
const EVP_MD * GetDigestPtr(VALUE obj)
const EVP_CIPHER * GetCipherPtr(VALUE obj)
VALUE rb_str_resize(VALUE, long)
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
static VALUE ossl_cipher_encrypt(int argc, VALUE *argv, VALUE self)
static int ossl_cipher_update_long(EVP_CIPHER_CTX *ctx, unsigned char *out, long *out_len_ptr, const unsigned char *in, long in_len)
VALUE rb_class_path(VALUE)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
VALUE rb_ivar_set(VALUE, ID, VALUE)
static VALUE ossl_cipher_copy(VALUE self, VALUE other)
#define ossl_cipher_set_auth_tag_len
static VALUE ossl_cipher_decrypt(int argc, VALUE *argv, VALUE self)
static VALUE ossl_cipher_key_length(VALUE self)
#define ossl_cipher_set_auth_tag
#define GetCipherInit(obj, ctx)
register unsigned int len
#define StringValueCStr(v)
static VALUE ossl_cipher_pkcs5_keyivgen(int argc, VALUE *argv, VALUE self)
void ossl_raise(VALUE exc, const char *fmt,...)
static VALUE ossl_cipher_reset(VALUE self)
void Init_ossl_cipher(void)
static VALUE ossl_cipher_set_padding(VALUE self, VALUE padding)
#define RSTRING_LENINT(str)
#define rb_check_frozen(obj)
static VALUE ossl_cipher_iv_length(VALUE self)
#define rb_intern_const(str)
VALUE rb_define_module(const char *name)
static VALUE ossl_cipher_set_key(VALUE self, VALUE key)
static VALUE ossl_cipher_name(VALUE self)
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
void rb_warn(const char *fmt,...)
static VALUE ossl_cipher_is_authenticated(VALUE self)
static VALUE ossl_cipher_set_iv(VALUE self, VALUE iv)
VALUE rb_attr_get(VALUE, ID)
static ID id_auth_tag_len
VALUE rb_str_new(const char *, long)
VALUE rb_obj_class(VALUE)