summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2023-11-18 09:37:15 +0000
committertb <>2023-11-18 09:37:15 +0000
commitcf1d9118861fb5ec267ff356834308151562d92d (patch)
tree6a57455fb90dc2e6329a93bfd6f50f475ffbf84e
parentc6a53967a0008fba21f8effe5960629cad4d4572 (diff)
downloadopenbsd-cf1d9118861fb5ec267ff356834308151562d92d.tar.gz
openbsd-cf1d9118861fb5ec267ff356834308151562d92d.tar.bz2
openbsd-cf1d9118861fb5ec267ff356834308151562d92d.zip
Check for negative IV length
A recent change in EVP_CIPHER_CTX_iv_length() made it possible in principle that this function returns -1. This can only happen for an incorrectly set up EVP_CIPHER. Still it is better form to check for negative lengths before stuffing it into a memcpy(). It would probably be desirable to cap the iv_length to something large enough. This can be done another time. ok beck
-rw-r--r--src/lib/libcrypto/evp/e_aes.c8
-rw-r--r--src/lib/libcrypto/evp/e_rc2.c14
-rw-r--r--src/lib/libcrypto/evp/evp_enc.c27
-rw-r--r--src/lib/libcrypto/evp/evp_lib.c12
-rw-r--r--src/lib/libcrypto/evp/p_seal.c11
5 files changed, 45 insertions, 27 deletions
diff --git a/src/lib/libcrypto/evp/e_aes.c b/src/lib/libcrypto/evp/e_aes.c
index 3d357f0119..eb7f520282 100644
--- a/src/lib/libcrypto/evp/e_aes.c
+++ b/src/lib/libcrypto/evp/e_aes.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: e_aes.c,v 1.54 2023/09/28 11:29:10 tb Exp $ */ 1/* $OpenBSD: e_aes.c,v 1.55 2023/11/18 09:37:15 tb Exp $ */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 2001-2011 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 2001-2011 The OpenSSL Project. All rights reserved.
4 * 4 *
@@ -2460,7 +2460,11 @@ aes_wrap_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
2460 } 2460 }
2461 2461
2462 if (iv != NULL) { 2462 if (iv != NULL) {
2463 memcpy(ctx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx)); 2463 int iv_len = EVP_CIPHER_CTX_iv_length(ctx);
2464
2465 if (iv_len < 0 || iv_len > sizeof(ctx->iv))
2466 return 0;
2467 memcpy(ctx->iv, iv, iv_len);
2464 wctx->iv = ctx->iv; 2468 wctx->iv = ctx->iv;
2465 } 2469 }
2466 2470
diff --git a/src/lib/libcrypto/evp/e_rc2.c b/src/lib/libcrypto/evp/e_rc2.c
index 32559e223f..501e2dd31f 100644
--- a/src/lib/libcrypto/evp/e_rc2.c
+++ b/src/lib/libcrypto/evp/e_rc2.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: e_rc2.c,v 1.22 2023/07/07 19:37:53 beck Exp $ */ 1/* $OpenBSD: e_rc2.c,v 1.23 2023/11/18 09:37:15 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -343,7 +343,7 @@ rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
343 343
344 if (type != NULL) { 344 if (type != NULL) {
345 l = EVP_CIPHER_CTX_iv_length(c); 345 l = EVP_CIPHER_CTX_iv_length(c);
346 if (l > sizeof(iv)) { 346 if (l < 0 || l > sizeof(iv)) {
347 EVPerror(EVP_R_IV_TOO_LARGE); 347 EVPerror(EVP_R_IV_TOO_LARGE);
348 return -1; 348 return -1;
349 } 349 }
@@ -373,6 +373,8 @@ rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
373 if (type != NULL) { 373 if (type != NULL) {
374 num = rc2_meth_to_magic(c); 374 num = rc2_meth_to_magic(c);
375 j = EVP_CIPHER_CTX_iv_length(c); 375 j = EVP_CIPHER_CTX_iv_length(c);
376 if (j < 0 || j > sizeof(c->oiv))
377 return 0;
376 i = ASN1_TYPE_set_int_octetstring(type, num, c->oiv, j); 378 i = ASN1_TYPE_set_int_octetstring(type, num, c->oiv, j);
377 } 379 }
378 return (i); 380 return (i);
@@ -381,9 +383,15 @@ rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
381static int 383static int
382rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) 384rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
383{ 385{
386 int iv_len;
387
384 switch (type) { 388 switch (type) {
385 case EVP_CTRL_INIT: 389 case EVP_CTRL_INIT:
386 data(c)->key_bits = EVP_CIPHER_CTX_key_length(c) * 8; 390 data(c)->key_bits = 0;
391 /* XXX - upper bound? */
392 if ((iv_len = EVP_CIPHER_CTX_key_length(c)) < 0)
393 return -1;
394 data(c)->key_bits = iv_len * 8;
387 return 1; 395 return 1;
388 396
389 case EVP_CTRL_GET_RC2_KEY_BITS: 397 case EVP_CTRL_GET_RC2_KEY_BITS:
diff --git a/src/lib/libcrypto/evp/evp_enc.c b/src/lib/libcrypto/evp/evp_enc.c
index 7534b4c9d2..eb279b2378 100644
--- a/src/lib/libcrypto/evp/evp_enc.c
+++ b/src/lib/libcrypto/evp/evp_enc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: evp_enc.c,v 1.53 2023/09/10 16:53:56 tb Exp $ */ 1/* $OpenBSD: evp_enc.c,v 1.54 2023/11/18 09:37:15 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -181,6 +181,8 @@ skip_to_init:
181 } 181 }
182 182
183 if (!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) { 183 if (!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) {
184 int iv_len;
185
184 switch (EVP_CIPHER_CTX_mode(ctx)) { 186 switch (EVP_CIPHER_CTX_mode(ctx)) {
185 187
186 case EVP_CIPH_STREAM_CIPHER: 188 case EVP_CIPH_STREAM_CIPHER:
@@ -194,25 +196,26 @@ skip_to_init:
194 /* fall-through */ 196 /* fall-through */
195 197
196 case EVP_CIPH_CBC_MODE: 198 case EVP_CIPH_CBC_MODE:
197 199 iv_len = EVP_CIPHER_CTX_iv_length(ctx);
198 if ((size_t)EVP_CIPHER_CTX_iv_length(ctx) > 200 if (iv_len < 0 || iv_len > sizeof(ctx->oiv)) {
199 sizeof(ctx->iv)) {
200 EVPerror(EVP_R_IV_TOO_LARGE); 201 EVPerror(EVP_R_IV_TOO_LARGE);
201 return 0; 202 return 0;
202 } 203 }
203 if (iv) 204 if (iv != NULL)
204 memcpy(ctx->oiv, iv, 205 memcpy(ctx->oiv, iv, iv_len);
205 EVP_CIPHER_CTX_iv_length(ctx)); 206 memcpy(ctx->iv, ctx->oiv, iv_len);
206 memcpy(ctx->iv, ctx->oiv,
207 EVP_CIPHER_CTX_iv_length(ctx));
208 break; 207 break;
209 208
210 case EVP_CIPH_CTR_MODE: 209 case EVP_CIPH_CTR_MODE:
211 ctx->num = 0; 210 ctx->num = 0;
211 iv_len = EVP_CIPHER_CTX_iv_length(ctx);
212 if (iv_len < 0 || iv_len > sizeof(ctx->iv)) {
213 EVPerror(EVP_R_IV_TOO_LARGE);
214 return 0;
215 }
212 /* Don't reuse IV for CTR mode */ 216 /* Don't reuse IV for CTR mode */
213 if (iv) 217 if (iv != NULL)
214 memcpy(ctx->iv, iv, 218 memcpy(ctx->iv, iv, iv_len);
215 EVP_CIPHER_CTX_iv_length(ctx));
216 break; 219 break;
217 220
218 default: 221 default:
diff --git a/src/lib/libcrypto/evp/evp_lib.c b/src/lib/libcrypto/evp/evp_lib.c
index f4e46aea41..55573b21db 100644
--- a/src/lib/libcrypto/evp/evp_lib.c
+++ b/src/lib/libcrypto/evp/evp_lib.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: evp_lib.c,v 1.28 2023/09/28 11:29:10 tb Exp $ */ 1/* $OpenBSD: evp_lib.c,v 1.29 2023/11/18 09:37:15 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -98,16 +98,16 @@ int
98EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) 98EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
99{ 99{
100 int i = 0; 100 int i = 0;
101 unsigned int l; 101 int l;
102 102
103 if (type != NULL) { 103 if (type != NULL) {
104 l = EVP_CIPHER_CTX_iv_length(c); 104 l = EVP_CIPHER_CTX_iv_length(c);
105 if (l > sizeof(c->iv)) { 105 if (l < 0 || l > sizeof(c->iv)) {
106 EVPerror(EVP_R_IV_TOO_LARGE); 106 EVPerror(EVP_R_IV_TOO_LARGE);
107 return 0; 107 return 0;
108 } 108 }
109 i = ASN1_TYPE_get_octetstring(type, c->oiv, l); 109 i = ASN1_TYPE_get_octetstring(type, c->oiv, l);
110 if (i != (int)l) 110 if (i != l)
111 return (-1); 111 return (-1);
112 else if (i > 0) 112 else if (i > 0)
113 memcpy(c->iv, c->oiv, l); 113 memcpy(c->iv, c->oiv, l);
@@ -119,11 +119,11 @@ int
119EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) 119EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
120{ 120{
121 int i = 0; 121 int i = 0;
122 unsigned int j; 122 int j;
123 123
124 if (type != NULL) { 124 if (type != NULL) {
125 j = EVP_CIPHER_CTX_iv_length(c); 125 j = EVP_CIPHER_CTX_iv_length(c);
126 if (j > sizeof(c->iv)) { 126 if (j < 0 || j > sizeof(c->iv)) {
127 EVPerror(EVP_R_IV_TOO_LARGE); 127 EVPerror(EVP_R_IV_TOO_LARGE);
128 return 0; 128 return 0;
129 } 129 }
diff --git a/src/lib/libcrypto/evp/p_seal.c b/src/lib/libcrypto/evp/p_seal.c
index b98da94360..7f29ea0ca2 100644
--- a/src/lib/libcrypto/evp/p_seal.c
+++ b/src/lib/libcrypto/evp/p_seal.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: p_seal.c,v 1.16 2023/07/07 19:37:54 beck Exp $ */ 1/* $OpenBSD: p_seal.c,v 1.17 2023/11/18 09:37:15 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -74,7 +74,7 @@ EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, unsigned char **ek,
74 int *ekl, unsigned char *iv, EVP_PKEY **pubk, int npubk) 74 int *ekl, unsigned char *iv, EVP_PKEY **pubk, int npubk)
75{ 75{
76 unsigned char key[EVP_MAX_KEY_LENGTH]; 76 unsigned char key[EVP_MAX_KEY_LENGTH];
77 int i; 77 int i, iv_len;
78 78
79 if (type) { 79 if (type) {
80 EVP_CIPHER_CTX_init(ctx); 80 EVP_CIPHER_CTX_init(ctx);
@@ -85,8 +85,11 @@ EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, unsigned char **ek,
85 return 1; 85 return 1;
86 if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0) 86 if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
87 return 0; 87 return 0;
88 if (EVP_CIPHER_CTX_iv_length(ctx)) 88 /* XXX - upper bound? */
89 arc4random_buf(iv, EVP_CIPHER_CTX_iv_length(ctx)); 89 if ((iv_len = EVP_CIPHER_CTX_iv_length(ctx)) < 0)
90 return 0;
91 if (iv_len > 0)
92 arc4random_buf(iv, iv_len);
90 93
91 if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv)) 94 if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv))
92 return 0; 95 return 0;