13 #define WrapCipher(obj, klass, ctx) \
14 (obj) = Data_Wrap_Struct((klass), 0, ossl_cipher_free, (ctx))
15 #define MakeCipher(obj, klass, ctx) \
16 (obj) = Data_Make_Struct((klass), EVP_CIPHER_CTX, 0, ossl_cipher_free, (ctx))
17 #define AllocCipher(obj, ctx) \
18 memset(DATA_PTR(obj) = (ctx) = ALLOC(EVP_CIPHER_CTX), 0, sizeof(EVP_CIPHER_CTX))
19 #define GetCipherInit(obj, ctx) do { \
20 Data_Get_Struct((obj), EVP_CIPHER_CTX, (ctx)); \
22 #define GetCipher(obj, ctx) do { \
23 GetCipherInit((obj), (ctx)); \
25 ossl_raise(rb_eRuntimeError, "Cipher not inititalized!"); \
28 #define SafeGetCipher(obj, ctx) do { \
29 OSSL_Check_Kind((obj), cCipher); \
30 GetCipher((obj), (ctx)); \
52 return EVP_CIPHER_CTX_cipher(ctx);
63 EVP_CIPHER_CTX_init(ctx);
77 EVP_CIPHER_CTX_cleanup(ctx);
104 const EVP_CIPHER *cipher;
113 EVP_CIPHER_CTX_init(ctx);
114 if (!(cipher = EVP_get_cipherbyname(name))) {
126 EVP_CIPHER_CTX *ctx1, *ctx2;
129 if (
self == other)
return self;
142 #ifdef HAVE_OBJ_NAME_DO_ALL_SORTED
144 add_cipher_name_to_ary(
const OBJ_NAME *
name,
VALUE ary)
151 #ifdef HAVE_OBJ_NAME_DO_ALL_SORTED
164 OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH,
165 (
void(*)(
const OBJ_NAME*,
void*))add_cipher_name_to_ary,
171 #define ossl_s_ciphers rb_f_notimplement
199 unsigned char key[EVP_MAX_KEY_LENGTH], *p_key =
NULL;
200 unsigned char iv[EVP_MAX_IV_LENGTH], *p_iv =
NULL;
211 "use %"PRIsVALUE"#pkcs5_keyivgen to derive key and IV",
212 cname, cname, cname);
215 if (
NIL_P(init_v)) memcpy(iv,
"OpenSSL for Ruby rulez!",
sizeof(iv));
219 memset(iv, 0, EVP_MAX_IV_LENGTH);
224 EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), EVP_md5(), iv,
300 const EVP_MD *digest;
301 VALUE vpass, vsalt, viter, vdigest;
302 unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH], *salt =
NULL;
305 rb_scan_args(argc, argv,
"13", &vpass, &vsalt, &viter, &vdigest);
316 EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), digest, salt,
329 const unsigned char *in,
long in_len)
333 #define UPDATE_LENGTH_LIMIT INT_MAX
335 #if SIZEOF_LONG > UPDATE_LENGTH_LIMIT
339 if (!EVP_CipherUpdate(ctx, out ? (out + out_len) : 0,
340 &out_part_len, in, in_part_len))
342 out_len += out_part_len;
347 if (!EVP_CipherUpdate(ctx, out ? (out + out_len) : 0,
348 &out_part_len, in, (
int)in_len))
350 if (out_len_ptr) *out_len_ptr = out_len += out_part_len;
372 long in_len, out_len;
385 out_len = in_len+EVP_CIPHER_CTX_block_size(ctx);
388 "data too big to make output buffer: %ld bytes", in_len);
428 str =
rb_str_new(0, EVP_CIPHER_CTX_block_size(ctx));
473 if (
RSTRING_LEN(key) < EVP_CIPHER_CTX_key_length(ctx))
506 if (
RSTRING_LEN(iv) < EVP_CIPHER_CTX_iv_length(ctx))
515 #ifdef HAVE_AUTHENTICATED_ENCRYPTION
539 long in_len, out_len;
554 #define ossl_is_gcm(nid) (nid) == NID_aes_128_gcm || \
555 (nid) == NID_aes_192_gcm || \
556 (nid) == NID_aes_256_gcm
559 ossl_get_gcm_auth_tag(EVP_CIPHER_CTX *ctx,
int len)
564 tag =
ALLOC_N(
unsigned char, len);
566 if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, len, tag))
602 nid = EVP_CIPHER_CTX_nid(ctx);
604 if (ossl_is_gcm(nid)) {
605 return ossl_get_gcm_auth_tag(ctx, tag_len);
613 ossl_set_gcm_auth_tag(EVP_CIPHER_CTX *ctx,
unsigned char *tag,
int tag_len)
615 if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, tag_len, tag))
644 nid = EVP_CIPHER_CTX_nid(ctx);
646 if (ossl_is_gcm(nid)) {
647 ossl_set_gcm_auth_tag(ctx, tag, tag_len);
669 nid = EVP_CIPHER_CTX_nid(ctx);
671 if (ossl_is_gcm(nid)) {
678 #define ossl_cipher_set_auth_data rb_f_notimplement
679 #define ossl_cipher_get_auth_tag rb_f_notimplement
680 #define ossl_cipher_set_auth_tag rb_f_notimplement
681 #define ossl_cipher_is_authenticated rb_f_notimplement
703 if (EVP_CIPHER_CTX_set_key_length(ctx, len) != 1)
709 #if defined(HAVE_EVP_CIPHER_CTX_SET_PADDING)
727 if (EVP_CIPHER_CTX_set_padding(ctx, pad) != 1)
732 #define ossl_cipher_set_padding rb_f_notimplement
735 #define CIPHER_0ARG_INT(func) \
737 ossl_cipher_##func(VALUE self) \
739 EVP_CIPHER_CTX *ctx; \
740 GetCipher(self, ctx); \
741 return INT2NUM(EVP_CIPHER_##func(EVP_CIPHER_CTX_cipher(ctx))); \
static VALUE ossl_cipher_alloc(VALUE klass)
#define ossl_cipher_set_auth_data
static VALUE ossl_cipher_final(VALUE self)
#define ossl_cipher_set_padding
#define OPENSSL_cleanse(p, l)
static VALUE ossl_cipher_init(int argc, VALUE *argv, VALUE self, int mode)
#define AllocCipher(obj, ctx)
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)
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)
#define EVP_CipherFinal_ex(ctx, outm, outl)
#define GetCipher(obj, ctx)
#define WrapCipher(obj, klass, ctx)
static VALUE ossl_cipher_set_key_length(VALUE self, VALUE key_length)
#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 CIPHER_0ARG_INT(func)
#define SafeGetCipher(obj, ctx)
RUBY_EXTERN VALUE rb_cObject
#define EVP_CipherInit_ex(ctx, type, impl, key, iv, enc)
#define ossl_cipher_get_auth_tag
#define EVP_CIPHER_name(e)
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)
static VALUE ossl_cipher_decrypt(int argc, VALUE *argv, VALUE self)
#define ossl_cipher_set_auth_tag
#define GetCipherInit(obj, ctx)
static VALUE ossl_cipher_pkcs5_keyivgen(int argc, VALUE *argv, VALUE self)
#define UPDATE_LENGTH_LIMIT
void ossl_raise(VALUE exc, const char *fmt,...)
static VALUE ossl_cipher_reset(VALUE self)
#define assert(condition)
#define StringValuePtr(v)
void Init_ossl_cipher(void)
#define RSTRING_LENINT(str)
#define rb_check_frozen(obj)
#define rb_intern_const(str)
VALUE rb_define_module(const char *name)
int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, EVP_CIPHER_CTX *in)
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)
VALUE rb_str_new2(const char *)
void rb_warn(const char *fmt,...)
static VALUE ossl_cipher_set_iv(VALUE self, VALUE iv)
#define ossl_cipher_is_authenticated
static void ossl_cipher_free(EVP_CIPHER_CTX *ctx)
VALUE rb_attr_get(VALUE, ID)
VALUE rb_str_new(const char *, long)
VALUE rb_obj_class(VALUE)