1 /* $OpenBSD: evp_lib.c,v 1.24 2022/01/10 13:42:28 tb Exp $ */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59 #include <stdio.h>
60 #include <string.h>
61
62 #include <openssl/err.h>
63 #include <openssl/evp.h>
64 #include <openssl/objects.h>
65
66 #include "asn1_locl.h"
67 #include "evp_locl.h"
68
69 int
EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX * c,ASN1_TYPE * type)70 EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
71 {
72 int ret;
73
74 if (c->cipher->set_asn1_parameters != NULL)
75 ret = c->cipher->set_asn1_parameters(c, type);
76 else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1)
77 ret = EVP_CIPHER_set_asn1_iv(c, type);
78 else
79 ret = -1;
80 return (ret);
81 }
82
83 int
EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX * c,ASN1_TYPE * type)84 EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
85 {
86 int ret;
87
88 if (c->cipher->get_asn1_parameters != NULL)
89 ret = c->cipher->get_asn1_parameters(c, type);
90 else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1)
91 ret = EVP_CIPHER_get_asn1_iv(c, type);
92 else
93 ret = -1;
94 return (ret);
95 }
96
97 int
EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX * c,ASN1_TYPE * type)98 EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
99 {
100 int i = 0;
101 unsigned int l;
102
103 if (type != NULL) {
104 l = EVP_CIPHER_CTX_iv_length(c);
105 if (l > sizeof(c->iv)) {
106 EVPerror(EVP_R_IV_TOO_LARGE);
107 return 0;
108 }
109 i = ASN1_TYPE_get_octetstring(type, c->oiv, l);
110 if (i != (int)l)
111 return (-1);
112 else if (i > 0)
113 memcpy(c->iv, c->oiv, l);
114 }
115 return (i);
116 }
117
118 int
EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX * c,ASN1_TYPE * type)119 EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
120 {
121 int i = 0;
122 unsigned int j;
123
124 if (type != NULL) {
125 j = EVP_CIPHER_CTX_iv_length(c);
126 if (j > sizeof(c->iv)) {
127 EVPerror(EVP_R_IV_TOO_LARGE);
128 return 0;
129 }
130 i = ASN1_TYPE_set_octetstring(type, c->oiv, j);
131 }
132 return (i);
133 }
134
135 /* Convert the various cipher NIDs and dummies to a proper OID NID */
136 int
EVP_CIPHER_type(const EVP_CIPHER * ctx)137 EVP_CIPHER_type(const EVP_CIPHER *ctx)
138 {
139 int nid;
140 ASN1_OBJECT *otmp;
141 nid = EVP_CIPHER_nid(ctx);
142
143 switch (nid) {
144 case NID_rc2_cbc:
145 case NID_rc2_64_cbc:
146 case NID_rc2_40_cbc:
147 return NID_rc2_cbc;
148
149 case NID_rc4:
150 case NID_rc4_40:
151 return NID_rc4;
152
153 case NID_aes_128_cfb128:
154 case NID_aes_128_cfb8:
155 case NID_aes_128_cfb1:
156 return NID_aes_128_cfb128;
157
158 case NID_aes_192_cfb128:
159 case NID_aes_192_cfb8:
160 case NID_aes_192_cfb1:
161 return NID_aes_192_cfb128;
162
163 case NID_aes_256_cfb128:
164 case NID_aes_256_cfb8:
165 case NID_aes_256_cfb1:
166 return NID_aes_256_cfb128;
167
168 case NID_des_cfb64:
169 case NID_des_cfb8:
170 case NID_des_cfb1:
171 return NID_des_cfb64;
172
173 case NID_des_ede3_cfb64:
174 case NID_des_ede3_cfb8:
175 case NID_des_ede3_cfb1:
176 return NID_des_cfb64;
177
178 default:
179 /* Check it has an OID and it is valid */
180 otmp = OBJ_nid2obj(nid);
181 if (!otmp || !otmp->data)
182 nid = NID_undef;
183 ASN1_OBJECT_free(otmp);
184 return nid;
185 }
186 }
187
188 int
EVP_CIPHER_block_size(const EVP_CIPHER * e)189 EVP_CIPHER_block_size(const EVP_CIPHER *e)
190 {
191 return e->block_size;
192 }
193
194 int
EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX * ctx)195 EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx)
196 {
197 return ctx->cipher->block_size;
198 }
199
200 int
EVP_Cipher(EVP_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,unsigned int inl)201 EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in,
202 unsigned int inl)
203 {
204 return ctx->cipher->do_cipher(ctx, out, in, inl);
205 }
206
207 const EVP_CIPHER *
EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX * ctx)208 EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx)
209 {
210 return ctx->cipher;
211 }
212
213 int
EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX * ctx)214 EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx)
215 {
216 return ctx->encrypt;
217 }
218
219 unsigned long
EVP_CIPHER_flags(const EVP_CIPHER * cipher)220 EVP_CIPHER_flags(const EVP_CIPHER *cipher)
221 {
222 return cipher->flags;
223 }
224
225 unsigned long
EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX * ctx)226 EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx)
227 {
228 return ctx->cipher->flags;
229 }
230
231 void *
EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX * ctx)232 EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx)
233 {
234 return ctx->app_data;
235 }
236
237 void
EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX * ctx,void * data)238 EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data)
239 {
240 ctx->app_data = data;
241 }
242
243 void *
EVP_CIPHER_CTX_get_cipher_data(const EVP_CIPHER_CTX * ctx)244 EVP_CIPHER_CTX_get_cipher_data(const EVP_CIPHER_CTX *ctx)
245 {
246 return ctx->cipher_data;
247 }
248
249 void *
EVP_CIPHER_CTX_set_cipher_data(EVP_CIPHER_CTX * ctx,void * cipher_data)250 EVP_CIPHER_CTX_set_cipher_data(EVP_CIPHER_CTX *ctx, void *cipher_data)
251 {
252 void *old_cipher_data;
253
254 old_cipher_data = ctx->cipher_data;
255 ctx->cipher_data = cipher_data;
256
257 return old_cipher_data;
258 }
259
260 int
EVP_CIPHER_iv_length(const EVP_CIPHER * cipher)261 EVP_CIPHER_iv_length(const EVP_CIPHER *cipher)
262 {
263 return cipher->iv_len;
264 }
265
266 int
EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX * ctx)267 EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx)
268 {
269 return ctx->cipher->iv_len;
270 }
271
272 unsigned char *
EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX * ctx)273 EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX *ctx)
274 {
275 return ctx->buf;
276 }
277
278 int
EVP_CIPHER_key_length(const EVP_CIPHER * cipher)279 EVP_CIPHER_key_length(const EVP_CIPHER *cipher)
280 {
281 return cipher->key_len;
282 }
283
284 int
EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX * ctx)285 EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx)
286 {
287 return ctx->key_len;
288 }
289
290 int
EVP_CIPHER_nid(const EVP_CIPHER * cipher)291 EVP_CIPHER_nid(const EVP_CIPHER *cipher)
292 {
293 return cipher->nid;
294 }
295
296 int
EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX * ctx)297 EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx)
298 {
299 return ctx->cipher->nid;
300 }
301
302 int
EVP_CIPHER_CTX_get_iv(const EVP_CIPHER_CTX * ctx,unsigned char * iv,size_t len)303 EVP_CIPHER_CTX_get_iv(const EVP_CIPHER_CTX *ctx, unsigned char *iv, size_t len)
304 {
305 if (ctx == NULL || len != EVP_CIPHER_CTX_iv_length(ctx))
306 return 0;
307 if (len > EVP_MAX_IV_LENGTH)
308 return 0; /* sanity check; shouldn't happen */
309 /*
310 * Skip the memcpy entirely when the requested IV length is zero,
311 * since the iv pointer may be NULL or invalid.
312 */
313 if (len != 0) {
314 if (iv == NULL)
315 return 0;
316 memcpy(iv, ctx->iv, len);
317 }
318 return 1;
319 }
320
321 int
EVP_CIPHER_CTX_set_iv(EVP_CIPHER_CTX * ctx,const unsigned char * iv,size_t len)322 EVP_CIPHER_CTX_set_iv(EVP_CIPHER_CTX *ctx, const unsigned char *iv, size_t len)
323 {
324 if (ctx == NULL || len != EVP_CIPHER_CTX_iv_length(ctx))
325 return 0;
326 if (len > EVP_MAX_IV_LENGTH)
327 return 0; /* sanity check; shouldn't happen */
328 /*
329 * Skip the memcpy entirely when the requested IV length is zero,
330 * since the iv pointer may be NULL or invalid.
331 */
332 if (len != 0) {
333 if (iv == NULL)
334 return 0;
335 memcpy(ctx->iv, iv, len);
336 }
337 return 1;
338 }
339
340 int
EVP_MD_block_size(const EVP_MD * md)341 EVP_MD_block_size(const EVP_MD *md)
342 {
343 return md->block_size;
344 }
345
346 int
EVP_MD_type(const EVP_MD * md)347 EVP_MD_type(const EVP_MD *md)
348 {
349 return md->type;
350 }
351
352 int
EVP_MD_pkey_type(const EVP_MD * md)353 EVP_MD_pkey_type(const EVP_MD *md)
354 {
355 return md->pkey_type;
356 }
357
358 int
EVP_MD_size(const EVP_MD * md)359 EVP_MD_size(const EVP_MD *md)
360 {
361 if (!md) {
362 EVPerror(EVP_R_MESSAGE_DIGEST_IS_NULL);
363 return -1;
364 }
365 return md->md_size;
366 }
367
368 unsigned long
EVP_MD_flags(const EVP_MD * md)369 EVP_MD_flags(const EVP_MD *md)
370 {
371 return md->flags;
372 }
373
374 EVP_MD *
EVP_MD_meth_new(int md_type,int pkey_type)375 EVP_MD_meth_new(int md_type, int pkey_type)
376 {
377 EVP_MD *md;
378
379 if ((md = calloc(1, sizeof(*md))) == NULL)
380 return NULL;
381
382 md->type = md_type;
383 md->pkey_type = pkey_type;
384
385 return md;
386 }
387
388 EVP_MD *
EVP_MD_meth_dup(const EVP_MD * md)389 EVP_MD_meth_dup(const EVP_MD *md)
390 {
391 EVP_MD *to;
392
393 if ((to = EVP_MD_meth_new(md->type, md->pkey_type)) == NULL)
394 return NULL;
395
396 memcpy(to, md, sizeof(*to));
397
398 return to;
399 }
400
401 void
EVP_MD_meth_free(EVP_MD * md)402 EVP_MD_meth_free(EVP_MD *md)
403 {
404 freezero(md, sizeof(*md));
405 }
406
407 int
EVP_MD_meth_set_input_blocksize(EVP_MD * md,int blocksize)408 EVP_MD_meth_set_input_blocksize(EVP_MD *md, int blocksize)
409 {
410 md->block_size = blocksize;
411 return 1;
412 }
413
414 int
EVP_MD_meth_set_result_size(EVP_MD * md,int result_size)415 EVP_MD_meth_set_result_size(EVP_MD *md, int result_size)
416 {
417 md->md_size = result_size;
418 return 1;
419 }
420
421 int
EVP_MD_meth_set_app_datasize(EVP_MD * md,int datasize)422 EVP_MD_meth_set_app_datasize(EVP_MD *md, int datasize)
423 {
424 md->ctx_size = datasize;
425 return 1;
426 }
427
428 int
EVP_MD_meth_set_flags(EVP_MD * md,unsigned long flags)429 EVP_MD_meth_set_flags(EVP_MD *md, unsigned long flags)
430 {
431 md->flags = flags;
432 return 1;
433 }
434
435 int
EVP_MD_meth_set_init(EVP_MD * md,int (* init)(EVP_MD_CTX * ctx))436 EVP_MD_meth_set_init(EVP_MD *md, int (*init)(EVP_MD_CTX *ctx))
437 {
438 md->init = init;
439 return 1;
440 }
441
442 int
EVP_MD_meth_set_update(EVP_MD * md,int (* update)(EVP_MD_CTX * ctx,const void * data,size_t count))443 EVP_MD_meth_set_update(EVP_MD *md,
444 int (*update)(EVP_MD_CTX *ctx, const void *data, size_t count))
445 {
446 md->update = update;
447 return 1;
448 }
449
450 int
EVP_MD_meth_set_final(EVP_MD * md,int (* final)(EVP_MD_CTX * ctx,unsigned char * md))451 EVP_MD_meth_set_final(EVP_MD *md,
452 int (*final)(EVP_MD_CTX *ctx, unsigned char *md))
453 {
454 md->final = final;
455 return 1;
456 }
457
458 int
EVP_MD_meth_set_copy(EVP_MD * md,int (* copy)(EVP_MD_CTX * to,const EVP_MD_CTX * from))459 EVP_MD_meth_set_copy(EVP_MD *md,
460 int (*copy)(EVP_MD_CTX *to, const EVP_MD_CTX *from))
461 {
462 md->copy = copy;
463 return 1;
464 }
465
466 int
EVP_MD_meth_set_cleanup(EVP_MD * md,int (* cleanup)(EVP_MD_CTX * ctx))467 EVP_MD_meth_set_cleanup(EVP_MD *md,
468 int (*cleanup)(EVP_MD_CTX *ctx))
469 {
470 md->cleanup = cleanup;
471 return 1;
472 }
473
474 int
EVP_MD_meth_set_ctrl(EVP_MD * md,int (* ctrl)(EVP_MD_CTX * ctx,int cmd,int p1,void * p2))475 EVP_MD_meth_set_ctrl(EVP_MD *md,
476 int (*ctrl)(EVP_MD_CTX *ctx, int cmd, int p1, void *p2))
477 {
478 md->md_ctrl = ctrl;
479 return 1;
480 }
481
482 const EVP_MD *
EVP_MD_CTX_md(const EVP_MD_CTX * ctx)483 EVP_MD_CTX_md(const EVP_MD_CTX *ctx)
484 {
485 if (!ctx)
486 return NULL;
487 return ctx->digest;
488 }
489
490 void *
EVP_MD_CTX_md_data(const EVP_MD_CTX * ctx)491 EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx)
492 {
493 return ctx->md_data;
494 }
495
496 EVP_PKEY_CTX *
EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX * ctx)497 EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx)
498 {
499 return ctx->pctx;
500 }
501
502 void
EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX * ctx,EVP_PKEY_CTX * pctx)503 EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx)
504 {
505 if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX)) {
506 EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
507 } else {
508 EVP_PKEY_CTX_free(ctx->pctx);
509 }
510
511 ctx->pctx = pctx;
512
513 if (pctx != NULL) {
514 /*
515 * For unclear reasons it was decided that the caller keeps
516 * ownership of pctx. So a flag was invented to make sure we
517 * don't free it in EVP_MD_CTX_cleanup(). We also need to
518 * unset it in EVP_MD_CTX_copy_ex(). Fortunately, the flag
519 * isn't public...
520 */
521 EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
522 }
523 }
524
525 void
EVP_MD_CTX_set_flags(EVP_MD_CTX * ctx,int flags)526 EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags)
527 {
528 ctx->flags |= flags;
529 }
530
531 void
EVP_MD_CTX_clear_flags(EVP_MD_CTX * ctx,int flags)532 EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags)
533 {
534 ctx->flags &= ~flags;
535 }
536
537 int
EVP_MD_CTX_test_flags(const EVP_MD_CTX * ctx,int flags)538 EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags)
539 {
540 return (ctx->flags & flags);
541 }
542
543 void
EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX * ctx,int flags)544 EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags)
545 {
546 ctx->flags |= flags;
547 }
548
549 void
EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX * ctx,int flags)550 EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags)
551 {
552 ctx->flags &= ~flags;
553 }
554
555 int
EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX * ctx,int flags)556 EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags)
557 {
558 return (ctx->flags & flags);
559 }
560