zig_example 0.2.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/ext/mkmf.rb +2734 -0
  3. data/ext/openssl/openssl_missing.c +40 -0
  4. data/ext/openssl/openssl_missing.h +238 -0
  5. data/ext/openssl/ossl.c +1295 -0
  6. data/ext/openssl/ossl.h +201 -0
  7. data/ext/openssl/ossl_asn1.c +1891 -0
  8. data/ext/openssl/ossl_asn1.h +62 -0
  9. data/ext/openssl/ossl_bio.c +42 -0
  10. data/ext/openssl/ossl_bio.h +16 -0
  11. data/ext/openssl/ossl_bn.c +1344 -0
  12. data/ext/openssl/ossl_bn.h +26 -0
  13. data/ext/openssl/ossl_cipher.c +1074 -0
  14. data/ext/openssl/ossl_cipher.h +20 -0
  15. data/ext/openssl/ossl_config.c +460 -0
  16. data/ext/openssl/ossl_config.h +16 -0
  17. data/ext/openssl/ossl_digest.c +425 -0
  18. data/ext/openssl/ossl_digest.h +20 -0
  19. data/ext/openssl/ossl_engine.c +568 -0
  20. data/ext/openssl/ossl_engine.h +19 -0
  21. data/ext/openssl/ossl_hmac.c +310 -0
  22. data/ext/openssl/ossl_hmac.h +18 -0
  23. data/ext/openssl/ossl_kdf.c +311 -0
  24. data/ext/openssl/ossl_kdf.h +6 -0
  25. data/ext/openssl/ossl_ns_spki.c +405 -0
  26. data/ext/openssl/ossl_ns_spki.h +19 -0
  27. data/ext/openssl/ossl_ocsp.c +1965 -0
  28. data/ext/openssl/ossl_ocsp.h +23 -0
  29. data/ext/openssl/ossl_pkcs12.c +275 -0
  30. data/ext/openssl/ossl_pkcs12.h +13 -0
  31. data/ext/openssl/ossl_pkcs7.c +1081 -0
  32. data/ext/openssl/ossl_pkcs7.h +36 -0
  33. data/ext/openssl/ossl_pkey.c +1624 -0
  34. data/ext/openssl/ossl_pkey.h +204 -0
  35. data/ext/openssl/ossl_pkey_dh.c +440 -0
  36. data/ext/openssl/ossl_pkey_dsa.c +359 -0
  37. data/ext/openssl/ossl_pkey_ec.c +1655 -0
  38. data/ext/openssl/ossl_pkey_rsa.c +579 -0
  39. data/ext/openssl/ossl_rand.c +200 -0
  40. data/ext/openssl/ossl_rand.h +18 -0
  41. data/ext/openssl/ossl_ssl.c +3142 -0
  42. data/ext/openssl/ossl_ssl.h +36 -0
  43. data/ext/openssl/ossl_ssl_session.c +331 -0
  44. data/ext/openssl/ossl_ts.c +1539 -0
  45. data/ext/openssl/ossl_ts.h +16 -0
  46. data/ext/openssl/ossl_x509.c +256 -0
  47. data/ext/openssl/ossl_x509.h +115 -0
  48. data/ext/openssl/ossl_x509attr.c +324 -0
  49. data/ext/openssl/ossl_x509cert.c +1002 -0
  50. data/ext/openssl/ossl_x509crl.c +545 -0
  51. data/ext/openssl/ossl_x509ext.c +490 -0
  52. data/ext/openssl/ossl_x509name.c +597 -0
  53. data/ext/openssl/ossl_x509req.c +444 -0
  54. data/ext/openssl/ossl_x509revoked.c +300 -0
  55. data/ext/openssl/ossl_x509store.c +986 -0
  56. data/ext/zigrb_100doors/build.zig +0 -12
  57. data/ext/zigrb_100doors/extconf.rb +2 -19
  58. data/ext/zigrb_ackermann/build.zig +0 -12
  59. data/ext/zigrb_ackermann/extconf.rb +2 -19
  60. data/ext/zigrb_lucas_lehmer/build.zig +53 -0
  61. data/ext/zigrb_lucas_lehmer/extconf.rb +3 -0
  62. data/ext/zigrb_lucas_lehmer/src/lucas_lehmer.c +60 -0
  63. data/ext/zigrb_lucas_lehmer/src/lucas_lehmer.h +1 -0
  64. data/ext/zigrb_lucas_lehmer/src/wrapper.zig +42 -0
  65. data/lib/zig_example/version.rb +1 -1
  66. data/lib/zig_example.rb +1 -0
  67. metadata +63 -3
@@ -0,0 +1,1074 @@
1
+ /*
2
+ * 'OpenSSL for Ruby' project
3
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
4
+ * All rights reserved.
5
+ */
6
+ /*
7
+ * This program is licensed under the same licence as Ruby.
8
+ * (See the file 'LICENCE'.)
9
+ */
10
+ #include "ossl.h"
11
+
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(); \
16
+ if (!(ctx)) \
17
+ ossl_raise(rb_eRuntimeError, NULL); \
18
+ RTYPEDDATA_DATA(obj) = (ctx); \
19
+ } while (0)
20
+ #define GetCipherInit(obj, ctx) do { \
21
+ TypedData_Get_Struct((obj), EVP_CIPHER_CTX, &ossl_cipher_type, (ctx)); \
22
+ } while (0)
23
+ #define GetCipher(obj, ctx) do { \
24
+ GetCipherInit((obj), (ctx)); \
25
+ if (!(ctx)) { \
26
+ ossl_raise(rb_eRuntimeError, "Cipher not initialized!"); \
27
+ } \
28
+ } while (0)
29
+
30
+ /*
31
+ * Classes
32
+ */
33
+ VALUE cCipher;
34
+ VALUE eCipherError;
35
+ static ID id_auth_tag_len, id_key_set;
36
+
37
+ static VALUE ossl_cipher_alloc(VALUE klass);
38
+ static void ossl_cipher_free(void *ptr);
39
+
40
+ static const rb_data_type_t ossl_cipher_type = {
41
+ "OpenSSL/Cipher",
42
+ {
43
+ 0, ossl_cipher_free,
44
+ },
45
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
46
+ };
47
+
48
+ /*
49
+ * PUBLIC
50
+ */
51
+ const EVP_CIPHER *
52
+ ossl_evp_get_cipherbyname(VALUE obj)
53
+ {
54
+ if (rb_obj_is_kind_of(obj, cCipher)) {
55
+ EVP_CIPHER_CTX *ctx;
56
+
57
+ GetCipher(obj, ctx);
58
+
59
+ return EVP_CIPHER_CTX_cipher(ctx);
60
+ }
61
+ else {
62
+ const EVP_CIPHER *cipher;
63
+
64
+ StringValueCStr(obj);
65
+ cipher = EVP_get_cipherbyname(RSTRING_PTR(obj));
66
+ if (!cipher)
67
+ ossl_raise(rb_eArgError,
68
+ "unsupported cipher algorithm: %"PRIsVALUE, obj);
69
+
70
+ return cipher;
71
+ }
72
+ }
73
+
74
+ VALUE
75
+ ossl_cipher_new(const EVP_CIPHER *cipher)
76
+ {
77
+ VALUE ret;
78
+ EVP_CIPHER_CTX *ctx;
79
+
80
+ ret = ossl_cipher_alloc(cCipher);
81
+ AllocCipher(ret, ctx);
82
+ if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, -1) != 1)
83
+ ossl_raise(eCipherError, NULL);
84
+
85
+ return ret;
86
+ }
87
+
88
+ /*
89
+ * PRIVATE
90
+ */
91
+ static void
92
+ ossl_cipher_free(void *ptr)
93
+ {
94
+ EVP_CIPHER_CTX_free(ptr);
95
+ }
96
+
97
+ static VALUE
98
+ ossl_cipher_alloc(VALUE klass)
99
+ {
100
+ return NewCipher(klass);
101
+ }
102
+
103
+ /*
104
+ * call-seq:
105
+ * Cipher.new(string) -> cipher
106
+ *
107
+ * The string must contain a valid cipher name like "aes-256-cbc".
108
+ *
109
+ * A list of cipher names is available by calling OpenSSL::Cipher.ciphers.
110
+ */
111
+ static VALUE
112
+ ossl_cipher_initialize(VALUE self, VALUE str)
113
+ {
114
+ EVP_CIPHER_CTX *ctx;
115
+ const EVP_CIPHER *cipher;
116
+ char *name;
117
+
118
+ name = StringValueCStr(str);
119
+ GetCipherInit(self, ctx);
120
+ if (ctx) {
121
+ ossl_raise(rb_eRuntimeError, "Cipher already initialized!");
122
+ }
123
+ AllocCipher(self, ctx);
124
+ if (!(cipher = EVP_get_cipherbyname(name))) {
125
+ ossl_raise(rb_eRuntimeError, "unsupported cipher algorithm (%"PRIsVALUE")", str);
126
+ }
127
+ if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, -1) != 1)
128
+ ossl_raise(eCipherError, NULL);
129
+
130
+ return self;
131
+ }
132
+
133
+ static VALUE
134
+ ossl_cipher_copy(VALUE self, VALUE other)
135
+ {
136
+ EVP_CIPHER_CTX *ctx1, *ctx2;
137
+
138
+ rb_check_frozen(self);
139
+ if (self == other) return self;
140
+
141
+ GetCipherInit(self, ctx1);
142
+ if (!ctx1) {
143
+ AllocCipher(self, ctx1);
144
+ }
145
+ GetCipher(other, ctx2);
146
+ if (EVP_CIPHER_CTX_copy(ctx1, ctx2) != 1)
147
+ ossl_raise(eCipherError, NULL);
148
+
149
+ return self;
150
+ }
151
+
152
+ static void
153
+ add_cipher_name_to_ary(const OBJ_NAME *name, void *arg)
154
+ {
155
+ VALUE ary = (VALUE)arg;
156
+ rb_ary_push(ary, rb_str_new2(name->name));
157
+ }
158
+
159
+ /*
160
+ * call-seq:
161
+ * OpenSSL::Cipher.ciphers -> array[string...]
162
+ *
163
+ * Returns the names of all available ciphers in an array.
164
+ */
165
+ static VALUE
166
+ ossl_s_ciphers(VALUE self)
167
+ {
168
+ VALUE ary;
169
+
170
+ ary = rb_ary_new();
171
+ OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH,
172
+ add_cipher_name_to_ary,
173
+ (void*)ary);
174
+
175
+ return ary;
176
+ }
177
+
178
+ /*
179
+ * call-seq:
180
+ * cipher.reset -> self
181
+ *
182
+ * Fully resets the internal state of the Cipher. By using this, the same
183
+ * Cipher instance may be used several times for encryption or decryption tasks.
184
+ *
185
+ * Internally calls EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, -1).
186
+ */
187
+ static VALUE
188
+ ossl_cipher_reset(VALUE self)
189
+ {
190
+ EVP_CIPHER_CTX *ctx;
191
+
192
+ GetCipher(self, ctx);
193
+ if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, -1) != 1)
194
+ ossl_raise(eCipherError, NULL);
195
+
196
+ return self;
197
+ }
198
+
199
+ static VALUE
200
+ ossl_cipher_init(int argc, VALUE *argv, VALUE self, int mode)
201
+ {
202
+ EVP_CIPHER_CTX *ctx;
203
+ unsigned char key[EVP_MAX_KEY_LENGTH], *p_key = NULL;
204
+ unsigned char iv[EVP_MAX_IV_LENGTH], *p_iv = NULL;
205
+ VALUE pass, init_v;
206
+
207
+ if(rb_scan_args(argc, argv, "02", &pass, &init_v) > 0){
208
+ /*
209
+ * oops. this code mistakes salt for IV.
210
+ * We deprecated the arguments for this method, but we decided
211
+ * keeping this behaviour for backward compatibility.
212
+ */
213
+ VALUE cname = rb_class_path(rb_obj_class(self));
214
+ rb_warn("arguments for %"PRIsVALUE"#encrypt and %"PRIsVALUE"#decrypt were deprecated; "
215
+ "use %"PRIsVALUE"#pkcs5_keyivgen to derive key and IV",
216
+ cname, cname, cname);
217
+ StringValue(pass);
218
+ GetCipher(self, ctx);
219
+ if (NIL_P(init_v)) memcpy(iv, "OpenSSL for Ruby rulez!", sizeof(iv));
220
+ else{
221
+ StringValue(init_v);
222
+ if (EVP_MAX_IV_LENGTH > RSTRING_LEN(init_v)) {
223
+ memset(iv, 0, EVP_MAX_IV_LENGTH);
224
+ memcpy(iv, RSTRING_PTR(init_v), RSTRING_LEN(init_v));
225
+ }
226
+ else memcpy(iv, RSTRING_PTR(init_v), sizeof(iv));
227
+ }
228
+ EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), EVP_md5(), iv,
229
+ (unsigned char *)RSTRING_PTR(pass), RSTRING_LENINT(pass), 1, key, NULL);
230
+ p_key = key;
231
+ p_iv = iv;
232
+ }
233
+ else {
234
+ GetCipher(self, ctx);
235
+ }
236
+ if (EVP_CipherInit_ex(ctx, NULL, NULL, p_key, p_iv, mode) != 1) {
237
+ ossl_raise(eCipherError, NULL);
238
+ }
239
+
240
+ rb_ivar_set(self, id_key_set, p_key ? Qtrue : Qfalse);
241
+
242
+ return self;
243
+ }
244
+
245
+ /*
246
+ * call-seq:
247
+ * cipher.encrypt -> self
248
+ *
249
+ * Initializes the Cipher for encryption.
250
+ *
251
+ * Make sure to call Cipher#encrypt or Cipher#decrypt before using any of the
252
+ * following methods:
253
+ * * [#key=, #iv=, #random_key, #random_iv, #pkcs5_keyivgen]
254
+ *
255
+ * Internally calls EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, 1).
256
+ */
257
+ static VALUE
258
+ ossl_cipher_encrypt(int argc, VALUE *argv, VALUE self)
259
+ {
260
+ return ossl_cipher_init(argc, argv, self, 1);
261
+ }
262
+
263
+ /*
264
+ * call-seq:
265
+ * cipher.decrypt -> self
266
+ *
267
+ * Initializes the Cipher for decryption.
268
+ *
269
+ * Make sure to call Cipher#encrypt or Cipher#decrypt before using any of the
270
+ * following methods:
271
+ * * [#key=, #iv=, #random_key, #random_iv, #pkcs5_keyivgen]
272
+ *
273
+ * Internally calls EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, 0).
274
+ */
275
+ static VALUE
276
+ ossl_cipher_decrypt(int argc, VALUE *argv, VALUE self)
277
+ {
278
+ return ossl_cipher_init(argc, argv, self, 0);
279
+ }
280
+
281
+ /*
282
+ * call-seq:
283
+ * cipher.pkcs5_keyivgen(pass, salt = nil, iterations = 2048, digest = "MD5") -> nil
284
+ *
285
+ * Generates and sets the key/IV based on a password.
286
+ *
287
+ * *WARNING*: This method is only PKCS5 v1.5 compliant when using RC2, RC4-40,
288
+ * or DES with MD5 or SHA1. Using anything else (like AES) will generate the
289
+ * key/iv using an OpenSSL specific method. This method is deprecated and
290
+ * should no longer be used. Use a PKCS5 v2 key generation method from
291
+ * OpenSSL::PKCS5 instead.
292
+ *
293
+ * === Parameters
294
+ * * _salt_ must be an 8 byte string if provided.
295
+ * * _iterations_ is an integer with a default of 2048.
296
+ * * _digest_ is a Digest object that defaults to 'MD5'
297
+ *
298
+ * A minimum of 1000 iterations is recommended.
299
+ *
300
+ */
301
+ static VALUE
302
+ ossl_cipher_pkcs5_keyivgen(int argc, VALUE *argv, VALUE self)
303
+ {
304
+ EVP_CIPHER_CTX *ctx;
305
+ const EVP_MD *digest;
306
+ VALUE vpass, vsalt, viter, vdigest;
307
+ unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH], *salt = NULL;
308
+ int iter;
309
+
310
+ rb_scan_args(argc, argv, "13", &vpass, &vsalt, &viter, &vdigest);
311
+ StringValue(vpass);
312
+ if(!NIL_P(vsalt)){
313
+ StringValue(vsalt);
314
+ if(RSTRING_LEN(vsalt) != PKCS5_SALT_LEN)
315
+ ossl_raise(eCipherError, "salt must be an 8-octet string");
316
+ salt = (unsigned char *)RSTRING_PTR(vsalt);
317
+ }
318
+ iter = NIL_P(viter) ? 2048 : NUM2INT(viter);
319
+ if (iter <= 0)
320
+ rb_raise(rb_eArgError, "iterations must be a positive integer");
321
+ digest = NIL_P(vdigest) ? EVP_md5() : ossl_evp_get_digestbyname(vdigest);
322
+ GetCipher(self, ctx);
323
+ EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), digest, salt,
324
+ (unsigned char *)RSTRING_PTR(vpass), RSTRING_LENINT(vpass), iter, key, iv);
325
+ if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, -1) != 1)
326
+ ossl_raise(eCipherError, NULL);
327
+ OPENSSL_cleanse(key, sizeof key);
328
+ OPENSSL_cleanse(iv, sizeof iv);
329
+
330
+ rb_ivar_set(self, id_key_set, Qtrue);
331
+
332
+ return Qnil;
333
+ }
334
+
335
+ static int
336
+ ossl_cipher_update_long(EVP_CIPHER_CTX *ctx, unsigned char *out, long *out_len_ptr,
337
+ const unsigned char *in, long in_len)
338
+ {
339
+ int out_part_len;
340
+ int limit = INT_MAX / 2 + 1;
341
+ long out_len = 0;
342
+
343
+ do {
344
+ int in_part_len = in_len > limit ? limit : (int)in_len;
345
+
346
+ if (!EVP_CipherUpdate(ctx, out ? (out + out_len) : 0,
347
+ &out_part_len, in, in_part_len))
348
+ return 0;
349
+
350
+ out_len += out_part_len;
351
+ in += in_part_len;
352
+ } while ((in_len -= limit) > 0);
353
+
354
+ if (out_len_ptr)
355
+ *out_len_ptr = out_len;
356
+
357
+ return 1;
358
+ }
359
+
360
+ /*
361
+ * call-seq:
362
+ * cipher.update(data [, buffer]) -> string or buffer
363
+ *
364
+ * Encrypts data in a streaming fashion. Hand consecutive blocks of data
365
+ * to the #update method in order to encrypt it. Returns the encrypted
366
+ * data chunk. When done, the output of Cipher#final should be additionally
367
+ * added to the result.
368
+ *
369
+ * If _buffer_ is given, the encryption/decryption result will be written to
370
+ * it. _buffer_ will be resized automatically.
371
+ */
372
+ static VALUE
373
+ ossl_cipher_update(int argc, VALUE *argv, VALUE self)
374
+ {
375
+ EVP_CIPHER_CTX *ctx;
376
+ unsigned char *in;
377
+ long in_len, out_len;
378
+ VALUE data, str;
379
+
380
+ rb_scan_args(argc, argv, "11", &data, &str);
381
+
382
+ if (!RTEST(rb_attr_get(self, id_key_set)))
383
+ ossl_raise(eCipherError, "key not set");
384
+
385
+ StringValue(data);
386
+ in = (unsigned char *)RSTRING_PTR(data);
387
+ in_len = RSTRING_LEN(data);
388
+ GetCipher(self, ctx);
389
+ out_len = in_len+EVP_CIPHER_CTX_block_size(ctx);
390
+ if (out_len <= 0) {
391
+ ossl_raise(rb_eRangeError,
392
+ "data too big to make output buffer: %ld bytes", in_len);
393
+ }
394
+
395
+ if (NIL_P(str)) {
396
+ str = rb_str_new(0, out_len);
397
+ } else {
398
+ StringValue(str);
399
+ rb_str_resize(str, out_len);
400
+ }
401
+
402
+ if (!ossl_cipher_update_long(ctx, (unsigned char *)RSTRING_PTR(str), &out_len, in, in_len))
403
+ ossl_raise(eCipherError, NULL);
404
+ assert(out_len < RSTRING_LEN(str));
405
+ rb_str_set_len(str, out_len);
406
+
407
+ return str;
408
+ }
409
+
410
+ /*
411
+ * call-seq:
412
+ * cipher.final -> string
413
+ *
414
+ * Returns the remaining data held in the cipher object. Further calls to
415
+ * Cipher#update or Cipher#final will return garbage. This call should always
416
+ * be made as the last call of an encryption or decryption operation, after
417
+ * having fed the entire plaintext or ciphertext to the Cipher instance.
418
+ *
419
+ * If an authenticated cipher was used, a CipherError is raised if the tag
420
+ * could not be authenticated successfully. Only call this method after
421
+ * setting the authentication tag and passing the entire contents of the
422
+ * ciphertext into the cipher.
423
+ */
424
+ static VALUE
425
+ ossl_cipher_final(VALUE self)
426
+ {
427
+ EVP_CIPHER_CTX *ctx;
428
+ int out_len;
429
+ VALUE str;
430
+
431
+ GetCipher(self, ctx);
432
+ str = rb_str_new(0, EVP_CIPHER_CTX_block_size(ctx));
433
+ if (!EVP_CipherFinal_ex(ctx, (unsigned char *)RSTRING_PTR(str), &out_len))
434
+ ossl_raise(eCipherError, NULL);
435
+ assert(out_len <= RSTRING_LEN(str));
436
+ rb_str_set_len(str, out_len);
437
+
438
+ return str;
439
+ }
440
+
441
+ /*
442
+ * call-seq:
443
+ * cipher.name -> string
444
+ *
445
+ * Returns the name of the cipher which may differ slightly from the original
446
+ * name provided.
447
+ */
448
+ static VALUE
449
+ ossl_cipher_name(VALUE self)
450
+ {
451
+ EVP_CIPHER_CTX *ctx;
452
+
453
+ GetCipher(self, ctx);
454
+
455
+ return rb_str_new2(EVP_CIPHER_name(EVP_CIPHER_CTX_cipher(ctx)));
456
+ }
457
+
458
+ /*
459
+ * call-seq:
460
+ * cipher.key = string -> string
461
+ *
462
+ * Sets the cipher key. To generate a key, you should either use a secure
463
+ * random byte string or, if the key is to be derived from a password, you
464
+ * should rely on PBKDF2 functionality provided by OpenSSL::PKCS5. To
465
+ * generate a secure random-based key, Cipher#random_key may be used.
466
+ *
467
+ * Only call this method after calling Cipher#encrypt or Cipher#decrypt.
468
+ */
469
+ static VALUE
470
+ ossl_cipher_set_key(VALUE self, VALUE key)
471
+ {
472
+ EVP_CIPHER_CTX *ctx;
473
+ int key_len;
474
+
475
+ StringValue(key);
476
+ GetCipher(self, ctx);
477
+
478
+ key_len = EVP_CIPHER_CTX_key_length(ctx);
479
+ if (RSTRING_LEN(key) != key_len)
480
+ ossl_raise(rb_eArgError, "key must be %d bytes", key_len);
481
+
482
+ if (EVP_CipherInit_ex(ctx, NULL, NULL, (unsigned char *)RSTRING_PTR(key), NULL, -1) != 1)
483
+ ossl_raise(eCipherError, NULL);
484
+
485
+ rb_ivar_set(self, id_key_set, Qtrue);
486
+
487
+ return key;
488
+ }
489
+
490
+ /*
491
+ * call-seq:
492
+ * cipher.iv = string -> string
493
+ *
494
+ * Sets the cipher IV. Please note that since you should never be using ECB
495
+ * mode, an IV is always explicitly required and should be set prior to
496
+ * encryption. The IV itself can be safely transmitted in public, but it
497
+ * should be unpredictable to prevent certain kinds of attacks. You may use
498
+ * Cipher#random_iv to create a secure random IV.
499
+ *
500
+ * Only call this method after calling Cipher#encrypt or Cipher#decrypt.
501
+ */
502
+ static VALUE
503
+ ossl_cipher_set_iv(VALUE self, VALUE iv)
504
+ {
505
+ EVP_CIPHER_CTX *ctx;
506
+ int iv_len = 0;
507
+
508
+ StringValue(iv);
509
+ GetCipher(self, ctx);
510
+
511
+ if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER)
512
+ iv_len = (int)(VALUE)EVP_CIPHER_CTX_get_app_data(ctx);
513
+ if (!iv_len)
514
+ iv_len = EVP_CIPHER_CTX_iv_length(ctx);
515
+ if (RSTRING_LEN(iv) != iv_len)
516
+ ossl_raise(rb_eArgError, "iv must be %d bytes", iv_len);
517
+
518
+ if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, (unsigned char *)RSTRING_PTR(iv), -1) != 1)
519
+ ossl_raise(eCipherError, NULL);
520
+
521
+ return iv;
522
+ }
523
+
524
+ /*
525
+ * call-seq:
526
+ * cipher.authenticated? -> true | false
527
+ *
528
+ * Indicated whether this Cipher instance uses an Authenticated Encryption
529
+ * mode.
530
+ */
531
+ static VALUE
532
+ ossl_cipher_is_authenticated(VALUE self)
533
+ {
534
+ EVP_CIPHER_CTX *ctx;
535
+
536
+ GetCipher(self, ctx);
537
+
538
+ return (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER) ? Qtrue : Qfalse;
539
+ }
540
+
541
+ /*
542
+ * call-seq:
543
+ * cipher.auth_data = string -> string
544
+ *
545
+ * Sets the cipher's additional authenticated data. This field must be
546
+ * set when using AEAD cipher modes such as GCM or CCM. If no associated
547
+ * data shall be used, this method must *still* be called with a value of "".
548
+ * The contents of this field should be non-sensitive data which will be
549
+ * added to the ciphertext to generate the authentication tag which validates
550
+ * the contents of the ciphertext.
551
+ *
552
+ * The AAD must be set prior to encryption or decryption. In encryption mode,
553
+ * it must be set after calling Cipher#encrypt and setting Cipher#key= and
554
+ * Cipher#iv=. When decrypting, the authenticated data must be set after key,
555
+ * iv and especially *after* the authentication tag has been set. I.e. set it
556
+ * only after calling Cipher#decrypt, Cipher#key=, Cipher#iv= and
557
+ * Cipher#auth_tag= first.
558
+ */
559
+ static VALUE
560
+ ossl_cipher_set_auth_data(VALUE self, VALUE data)
561
+ {
562
+ EVP_CIPHER_CTX *ctx;
563
+ unsigned char *in;
564
+ long in_len, out_len;
565
+
566
+ StringValue(data);
567
+
568
+ in = (unsigned char *) RSTRING_PTR(data);
569
+ in_len = RSTRING_LEN(data);
570
+
571
+ GetCipher(self, ctx);
572
+ if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER))
573
+ ossl_raise(eCipherError, "AEAD not supported by this cipher");
574
+
575
+ if (!ossl_cipher_update_long(ctx, NULL, &out_len, in, in_len))
576
+ ossl_raise(eCipherError, "couldn't set additional authenticated data");
577
+
578
+ return data;
579
+ }
580
+
581
+ /*
582
+ * call-seq:
583
+ * cipher.auth_tag(tag_len = 16) -> String
584
+ *
585
+ * Gets the authentication tag generated by Authenticated Encryption Cipher
586
+ * modes (GCM for example). This tag may be stored along with the ciphertext,
587
+ * then set on the decryption cipher to authenticate the contents of the
588
+ * ciphertext against changes. If the optional integer parameter _tag_len_ is
589
+ * given, the returned tag will be _tag_len_ bytes long. If the parameter is
590
+ * omitted, the default length of 16 bytes or the length previously set by
591
+ * #auth_tag_len= will be used. For maximum security, the longest possible
592
+ * should be chosen.
593
+ *
594
+ * The tag may only be retrieved after calling Cipher#final.
595
+ */
596
+ static VALUE
597
+ ossl_cipher_get_auth_tag(int argc, VALUE *argv, VALUE self)
598
+ {
599
+ VALUE vtag_len, ret;
600
+ EVP_CIPHER_CTX *ctx;
601
+ int tag_len = 16;
602
+
603
+ rb_scan_args(argc, argv, "01", &vtag_len);
604
+ if (NIL_P(vtag_len))
605
+ vtag_len = rb_attr_get(self, id_auth_tag_len);
606
+ if (!NIL_P(vtag_len))
607
+ tag_len = NUM2INT(vtag_len);
608
+
609
+ GetCipher(self, ctx);
610
+
611
+ if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER))
612
+ ossl_raise(eCipherError, "authentication tag not supported by this cipher");
613
+
614
+ ret = rb_str_new(NULL, tag_len);
615
+ if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, tag_len, RSTRING_PTR(ret)))
616
+ ossl_raise(eCipherError, "retrieving the authentication tag failed");
617
+
618
+ return ret;
619
+ }
620
+
621
+ /*
622
+ * call-seq:
623
+ * cipher.auth_tag = string -> string
624
+ *
625
+ * Sets the authentication tag to verify the integrity of the ciphertext.
626
+ * This can be called only when the cipher supports AE. The tag must be set
627
+ * after calling Cipher#decrypt, Cipher#key= and Cipher#iv=, but before
628
+ * calling Cipher#final. After all decryption is performed, the tag is
629
+ * verified automatically in the call to Cipher#final.
630
+ *
631
+ * For OCB mode, the tag length must be supplied with #auth_tag_len=
632
+ * beforehand.
633
+ */
634
+ static VALUE
635
+ ossl_cipher_set_auth_tag(VALUE self, VALUE vtag)
636
+ {
637
+ EVP_CIPHER_CTX *ctx;
638
+ unsigned char *tag;
639
+ int tag_len;
640
+
641
+ StringValue(vtag);
642
+ tag = (unsigned char *) RSTRING_PTR(vtag);
643
+ tag_len = RSTRING_LENINT(vtag);
644
+
645
+ GetCipher(self, ctx);
646
+ if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER))
647
+ ossl_raise(eCipherError, "authentication tag not supported by this cipher");
648
+
649
+ if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tag_len, tag))
650
+ ossl_raise(eCipherError, "unable to set AEAD tag");
651
+
652
+ return vtag;
653
+ }
654
+
655
+ /*
656
+ * call-seq:
657
+ * cipher.auth_tag_len = Integer -> Integer
658
+ *
659
+ * Sets the length of the authentication tag to be generated or to be given for
660
+ * AEAD ciphers that requires it as in input parameter. Note that not all AEAD
661
+ * ciphers support this method.
662
+ *
663
+ * In OCB mode, the length must be supplied both when encrypting and when
664
+ * decrypting, and must be before specifying an IV.
665
+ */
666
+ static VALUE
667
+ ossl_cipher_set_auth_tag_len(VALUE self, VALUE vlen)
668
+ {
669
+ int tag_len = NUM2INT(vlen);
670
+ EVP_CIPHER_CTX *ctx;
671
+
672
+ GetCipher(self, ctx);
673
+ if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER))
674
+ ossl_raise(eCipherError, "AEAD not supported by this cipher");
675
+
676
+ if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tag_len, NULL))
677
+ ossl_raise(eCipherError, "unable to set authentication tag length");
678
+
679
+ /* for #auth_tag */
680
+ rb_ivar_set(self, id_auth_tag_len, INT2NUM(tag_len));
681
+
682
+ return vlen;
683
+ }
684
+
685
+ /*
686
+ * call-seq:
687
+ * cipher.iv_len = integer -> integer
688
+ *
689
+ * Sets the IV/nonce length of the Cipher. Normally block ciphers don't allow
690
+ * changing the IV length, but some make use of IV for 'nonce'. You may need
691
+ * this for interoperability with other applications.
692
+ */
693
+ static VALUE
694
+ ossl_cipher_set_iv_length(VALUE self, VALUE iv_length)
695
+ {
696
+ int len = NUM2INT(iv_length);
697
+ EVP_CIPHER_CTX *ctx;
698
+
699
+ GetCipher(self, ctx);
700
+ if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER))
701
+ ossl_raise(eCipherError, "cipher does not support AEAD");
702
+
703
+ if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, len, NULL))
704
+ ossl_raise(eCipherError, "unable to set IV length");
705
+
706
+ /*
707
+ * EVP_CIPHER_CTX_iv_length() returns the default length. So we need to save
708
+ * the length somewhere. Luckily currently we aren't using app_data.
709
+ */
710
+ EVP_CIPHER_CTX_set_app_data(ctx, (void *)(VALUE)len);
711
+
712
+ return iv_length;
713
+ }
714
+
715
+ /*
716
+ * call-seq:
717
+ * cipher.key_len = integer -> integer
718
+ *
719
+ * Sets the key length of the cipher. If the cipher is a fixed length cipher
720
+ * then attempting to set the key length to any value other than the fixed
721
+ * value is an error.
722
+ *
723
+ * Under normal circumstances you do not need to call this method (and probably shouldn't).
724
+ *
725
+ * See EVP_CIPHER_CTX_set_key_length for further information.
726
+ */
727
+ static VALUE
728
+ ossl_cipher_set_key_length(VALUE self, VALUE key_length)
729
+ {
730
+ int len = NUM2INT(key_length);
731
+ EVP_CIPHER_CTX *ctx;
732
+
733
+ GetCipher(self, ctx);
734
+ if (EVP_CIPHER_CTX_set_key_length(ctx, len) != 1)
735
+ ossl_raise(eCipherError, NULL);
736
+
737
+ return key_length;
738
+ }
739
+
740
+ /*
741
+ * call-seq:
742
+ * cipher.padding = integer -> integer
743
+ *
744
+ * Enables or disables padding. By default encryption operations are padded using standard block padding and the
745
+ * padding is checked and removed when decrypting. If the pad parameter is zero then no padding is performed, the
746
+ * total amount of data encrypted or decrypted must then be a multiple of the block size or an error will occur.
747
+ *
748
+ * See EVP_CIPHER_CTX_set_padding for further information.
749
+ */
750
+ static VALUE
751
+ ossl_cipher_set_padding(VALUE self, VALUE padding)
752
+ {
753
+ EVP_CIPHER_CTX *ctx;
754
+ int pad = NUM2INT(padding);
755
+
756
+ GetCipher(self, ctx);
757
+ if (EVP_CIPHER_CTX_set_padding(ctx, pad) != 1)
758
+ ossl_raise(eCipherError, NULL);
759
+ return padding;
760
+ }
761
+
762
+ /*
763
+ * call-seq:
764
+ * cipher.key_len -> integer
765
+ *
766
+ * Returns the key length in bytes of the Cipher.
767
+ */
768
+ static VALUE
769
+ ossl_cipher_key_length(VALUE self)
770
+ {
771
+ EVP_CIPHER_CTX *ctx;
772
+
773
+ GetCipher(self, ctx);
774
+
775
+ return INT2NUM(EVP_CIPHER_CTX_key_length(ctx));
776
+ }
777
+
778
+ /*
779
+ * call-seq:
780
+ * cipher.iv_len -> integer
781
+ *
782
+ * Returns the expected length in bytes for an IV for this Cipher.
783
+ */
784
+ static VALUE
785
+ ossl_cipher_iv_length(VALUE self)
786
+ {
787
+ EVP_CIPHER_CTX *ctx;
788
+ int len = 0;
789
+
790
+ GetCipher(self, ctx);
791
+ if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER)
792
+ len = (int)(VALUE)EVP_CIPHER_CTX_get_app_data(ctx);
793
+ if (!len)
794
+ len = EVP_CIPHER_CTX_iv_length(ctx);
795
+
796
+ return INT2NUM(len);
797
+ }
798
+
799
+ /*
800
+ * call-seq:
801
+ * cipher.block_size -> integer
802
+ *
803
+ * Returns the size in bytes of the blocks on which this Cipher operates on.
804
+ */
805
+ static VALUE
806
+ ossl_cipher_block_size(VALUE self)
807
+ {
808
+ EVP_CIPHER_CTX *ctx;
809
+
810
+ GetCipher(self, ctx);
811
+
812
+ return INT2NUM(EVP_CIPHER_CTX_block_size(ctx));
813
+ }
814
+
815
+ /*
816
+ * call-seq:
817
+ * cipher.ccm_data_len = integer -> integer
818
+ *
819
+ * Sets the length of the plaintext / ciphertext message that will be
820
+ * processed in CCM mode. Make sure to call this method after #key= and
821
+ * #iv= have been set, and before #auth_data=.
822
+ *
823
+ * Only call this method after calling Cipher#encrypt or Cipher#decrypt.
824
+ */
825
+ static VALUE
826
+ ossl_cipher_set_ccm_data_len(VALUE self, VALUE data_len)
827
+ {
828
+ int in_len, out_len;
829
+ EVP_CIPHER_CTX *ctx;
830
+
831
+ in_len = NUM2INT(data_len);
832
+
833
+ GetCipher(self, ctx);
834
+ if (EVP_CipherUpdate(ctx, NULL, &out_len, NULL, in_len) != 1)
835
+ ossl_raise(eCipherError, NULL);
836
+
837
+ return data_len;
838
+ }
839
+
840
+ /*
841
+ * INIT
842
+ */
843
+ void
844
+ Init_ossl_cipher(void)
845
+ {
846
+ #if 0
847
+ mOSSL = rb_define_module("OpenSSL");
848
+ eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
849
+ #endif
850
+
851
+ /* Document-class: OpenSSL::Cipher
852
+ *
853
+ * Provides symmetric algorithms for encryption and decryption. The
854
+ * algorithms that are available depend on the particular version
855
+ * of OpenSSL that is installed.
856
+ *
857
+ * === Listing all supported algorithms
858
+ *
859
+ * A list of supported algorithms can be obtained by
860
+ *
861
+ * puts OpenSSL::Cipher.ciphers
862
+ *
863
+ * === Instantiating a Cipher
864
+ *
865
+ * There are several ways to create a Cipher instance. Generally, a
866
+ * Cipher algorithm is categorized by its name, the key length in bits
867
+ * and the cipher mode to be used. The most generic way to create a
868
+ * Cipher is the following
869
+ *
870
+ * cipher = OpenSSL::Cipher.new('<name>-<key length>-<mode>')
871
+ *
872
+ * That is, a string consisting of the hyphenated concatenation of the
873
+ * individual components name, key length and mode. Either all uppercase
874
+ * or all lowercase strings may be used, for example:
875
+ *
876
+ * cipher = OpenSSL::Cipher.new('aes-128-cbc')
877
+ *
878
+ * === Choosing either encryption or decryption mode
879
+ *
880
+ * Encryption and decryption are often very similar operations for
881
+ * symmetric algorithms, this is reflected by not having to choose
882
+ * different classes for either operation, both can be done using the
883
+ * same class. Still, after obtaining a Cipher instance, we need to
884
+ * tell the instance what it is that we intend to do with it, so we
885
+ * need to call either
886
+ *
887
+ * cipher.encrypt
888
+ *
889
+ * or
890
+ *
891
+ * cipher.decrypt
892
+ *
893
+ * on the Cipher instance. This should be the first call after creating
894
+ * the instance, otherwise configuration that has already been set could
895
+ * get lost in the process.
896
+ *
897
+ * === Choosing a key
898
+ *
899
+ * Symmetric encryption requires a key that is the same for the encrypting
900
+ * and for the decrypting party and after initial key establishment should
901
+ * be kept as private information. There are a lot of ways to create
902
+ * insecure keys, the most notable is to simply take a password as the key
903
+ * without processing the password further. A simple and secure way to
904
+ * create a key for a particular Cipher is
905
+ *
906
+ * cipher = OpenSSL::Cipher.new('aes-256-cfb')
907
+ * cipher.encrypt
908
+ * key = cipher.random_key # also sets the generated key on the Cipher
909
+ *
910
+ * If you absolutely need to use passwords as encryption keys, you
911
+ * should use Password-Based Key Derivation Function 2 (PBKDF2) by
912
+ * generating the key with the help of the functionality provided by
913
+ * OpenSSL::PKCS5.pbkdf2_hmac_sha1 or OpenSSL::PKCS5.pbkdf2_hmac.
914
+ *
915
+ * Although there is Cipher#pkcs5_keyivgen, its use is deprecated and
916
+ * it should only be used in legacy applications because it does not use
917
+ * the newer PKCS#5 v2 algorithms.
918
+ *
919
+ * === Choosing an IV
920
+ *
921
+ * The cipher modes CBC, CFB, OFB and CTR all need an "initialization
922
+ * vector", or short, IV. ECB mode is the only mode that does not require
923
+ * an IV, but there is almost no legitimate use case for this mode
924
+ * because of the fact that it does not sufficiently hide plaintext
925
+ * patterns. Therefore
926
+ *
927
+ * <b>You should never use ECB mode unless you are absolutely sure that
928
+ * you absolutely need it</b>
929
+ *
930
+ * Because of this, you will end up with a mode that explicitly requires
931
+ * an IV in any case. Although the IV can be seen as public information,
932
+ * i.e. it may be transmitted in public once generated, it should still
933
+ * stay unpredictable to prevent certain kinds of attacks. Therefore,
934
+ * ideally
935
+ *
936
+ * <b>Always create a secure random IV for every encryption of your
937
+ * Cipher</b>
938
+ *
939
+ * A new, random IV should be created for every encryption of data. Think
940
+ * of the IV as a nonce (number used once) - it's public but random and
941
+ * unpredictable. A secure random IV can be created as follows
942
+ *
943
+ * cipher = ...
944
+ * cipher.encrypt
945
+ * key = cipher.random_key
946
+ * iv = cipher.random_iv # also sets the generated IV on the Cipher
947
+ *
948
+ * Although the key is generally a random value, too, it is a bad choice
949
+ * as an IV. There are elaborate ways how an attacker can take advantage
950
+ * of such an IV. As a general rule of thumb, exposing the key directly
951
+ * or indirectly should be avoided at all cost and exceptions only be
952
+ * made with good reason.
953
+ *
954
+ * === Calling Cipher#final
955
+ *
956
+ * ECB (which should not be used) and CBC are both block-based modes.
957
+ * This means that unlike for the other streaming-based modes, they
958
+ * operate on fixed-size blocks of data, and therefore they require a
959
+ * "finalization" step to produce or correctly decrypt the last block of
960
+ * data by appropriately handling some form of padding. Therefore it is
961
+ * essential to add the output of OpenSSL::Cipher#final to your
962
+ * encryption/decryption buffer or you will end up with decryption errors
963
+ * or truncated data.
964
+ *
965
+ * Although this is not really necessary for streaming-mode ciphers, it is
966
+ * still recommended to apply the same pattern of adding the output of
967
+ * Cipher#final there as well - it also enables you to switch between
968
+ * modes more easily in the future.
969
+ *
970
+ * === Encrypting and decrypting some data
971
+ *
972
+ * data = "Very, very confidential data"
973
+ *
974
+ * cipher = OpenSSL::Cipher.new('aes-128-cbc')
975
+ * cipher.encrypt
976
+ * key = cipher.random_key
977
+ * iv = cipher.random_iv
978
+ *
979
+ * encrypted = cipher.update(data) + cipher.final
980
+ * ...
981
+ * decipher = OpenSSL::Cipher.new('aes-128-cbc')
982
+ * decipher.decrypt
983
+ * decipher.key = key
984
+ * decipher.iv = iv
985
+ *
986
+ * plain = decipher.update(encrypted) + decipher.final
987
+ *
988
+ * puts data == plain #=> true
989
+ *
990
+ * === Authenticated Encryption and Associated Data (AEAD)
991
+ *
992
+ * If the OpenSSL version used supports it, an Authenticated Encryption
993
+ * mode (such as GCM or CCM) should always be preferred over any
994
+ * unauthenticated mode. Currently, OpenSSL supports AE only in combination
995
+ * with Associated Data (AEAD) where additional associated data is included
996
+ * in the encryption process to compute a tag at the end of the encryption.
997
+ * This tag will also be used in the decryption process and by verifying
998
+ * its validity, the authenticity of a given ciphertext is established.
999
+ *
1000
+ * This is superior to unauthenticated modes in that it allows to detect
1001
+ * if somebody effectively changed the ciphertext after it had been
1002
+ * encrypted. This prevents malicious modifications of the ciphertext that
1003
+ * could otherwise be exploited to modify ciphertexts in ways beneficial to
1004
+ * potential attackers.
1005
+ *
1006
+ * An associated data is used where there is additional information, such as
1007
+ * headers or some metadata, that must be also authenticated but not
1008
+ * necessarily need to be encrypted. If no associated data is needed for
1009
+ * encryption and later decryption, the OpenSSL library still requires a
1010
+ * value to be set - "" may be used in case none is available.
1011
+ *
1012
+ * An example using the GCM (Galois/Counter Mode). You have 16 bytes _key_,
1013
+ * 12 bytes (96 bits) _nonce_ and the associated data _auth_data_. Be sure
1014
+ * not to reuse the _key_ and _nonce_ pair. Reusing an nonce ruins the
1015
+ * security guarantees of GCM mode.
1016
+ *
1017
+ * cipher = OpenSSL::Cipher.new('aes-128-gcm').encrypt
1018
+ * cipher.key = key
1019
+ * cipher.iv = nonce
1020
+ * cipher.auth_data = auth_data
1021
+ *
1022
+ * encrypted = cipher.update(data) + cipher.final
1023
+ * tag = cipher.auth_tag # produces 16 bytes tag by default
1024
+ *
1025
+ * Now you are the receiver. You know the _key_ and have received _nonce_,
1026
+ * _auth_data_, _encrypted_ and _tag_ through an untrusted network. Note
1027
+ * that GCM accepts an arbitrary length tag between 1 and 16 bytes. You may
1028
+ * additionally need to check that the received tag has the correct length,
1029
+ * or you allow attackers to forge a valid single byte tag for the tampered
1030
+ * ciphertext with a probability of 1/256.
1031
+ *
1032
+ * raise "tag is truncated!" unless tag.bytesize == 16
1033
+ * decipher = OpenSSL::Cipher.new('aes-128-gcm').decrypt
1034
+ * decipher.key = key
1035
+ * decipher.iv = nonce
1036
+ * decipher.auth_tag = tag
1037
+ * decipher.auth_data = auth_data
1038
+ *
1039
+ * decrypted = decipher.update(encrypted) + decipher.final
1040
+ *
1041
+ * puts data == decrypted #=> true
1042
+ */
1043
+ cCipher = rb_define_class_under(mOSSL, "Cipher", rb_cObject);
1044
+ eCipherError = rb_define_class_under(cCipher, "CipherError", eOSSLError);
1045
+
1046
+ rb_define_alloc_func(cCipher, ossl_cipher_alloc);
1047
+ rb_define_method(cCipher, "initialize_copy", ossl_cipher_copy, 1);
1048
+ rb_define_module_function(cCipher, "ciphers", ossl_s_ciphers, 0);
1049
+ rb_define_method(cCipher, "initialize", ossl_cipher_initialize, 1);
1050
+ rb_define_method(cCipher, "reset", ossl_cipher_reset, 0);
1051
+ rb_define_method(cCipher, "encrypt", ossl_cipher_encrypt, -1);
1052
+ rb_define_method(cCipher, "decrypt", ossl_cipher_decrypt, -1);
1053
+ rb_define_method(cCipher, "pkcs5_keyivgen", ossl_cipher_pkcs5_keyivgen, -1);
1054
+ rb_define_method(cCipher, "update", ossl_cipher_update, -1);
1055
+ rb_define_method(cCipher, "final", ossl_cipher_final, 0);
1056
+ rb_define_method(cCipher, "name", ossl_cipher_name, 0);
1057
+ rb_define_method(cCipher, "key=", ossl_cipher_set_key, 1);
1058
+ rb_define_method(cCipher, "auth_data=", ossl_cipher_set_auth_data, 1);
1059
+ rb_define_method(cCipher, "auth_tag=", ossl_cipher_set_auth_tag, 1);
1060
+ rb_define_method(cCipher, "auth_tag", ossl_cipher_get_auth_tag, -1);
1061
+ rb_define_method(cCipher, "auth_tag_len=", ossl_cipher_set_auth_tag_len, 1);
1062
+ rb_define_method(cCipher, "authenticated?", ossl_cipher_is_authenticated, 0);
1063
+ rb_define_method(cCipher, "key_len=", ossl_cipher_set_key_length, 1);
1064
+ rb_define_method(cCipher, "key_len", ossl_cipher_key_length, 0);
1065
+ rb_define_method(cCipher, "iv=", ossl_cipher_set_iv, 1);
1066
+ rb_define_method(cCipher, "iv_len=", ossl_cipher_set_iv_length, 1);
1067
+ rb_define_method(cCipher, "iv_len", ossl_cipher_iv_length, 0);
1068
+ rb_define_method(cCipher, "block_size", ossl_cipher_block_size, 0);
1069
+ rb_define_method(cCipher, "padding=", ossl_cipher_set_padding, 1);
1070
+ rb_define_method(cCipher, "ccm_data_len=", ossl_cipher_set_ccm_data_len, 1);
1071
+
1072
+ id_auth_tag_len = rb_intern_const("auth_tag_len");
1073
+ id_key_set = rb_intern_const("key_set");
1074
+ }