diff options
| author | tb <> | 2022-07-24 18:55:22 +0000 |
|---|---|---|
| committer | tb <> | 2022-07-24 18:55:22 +0000 |
| commit | 77022ecd888ca24de1871ac90ae75c8471ee57ae (patch) | |
| tree | ffbba431b75ee87c59536bb5d3c98200ccc27f2a /src | |
| parent | fccf1a5245040eebcdbf7a7c3eea04e855ebf7e1 (diff) | |
| download | openbsd-77022ecd888ca24de1871ac90ae75c8471ee57ae.tar.gz openbsd-77022ecd888ca24de1871ac90ae75c8471ee57ae.tar.bz2 openbsd-77022ecd888ca24de1871ac90ae75c8471ee57ae.zip | |
Align PKCS12_key_gen_uni() with OpenSSL
This is Dr Stephen Henson's rewrite avoiding BIGNUM (OpenSSL 54c68d35).
Additionally this pulls in a < vs <= fix by Pauli Dale (OpenSSL 9d868840).
There is also some minor cleanup by myself.
ok jsing
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libcrypto/pkcs12/p12_key.c | 108 |
1 files changed, 50 insertions, 58 deletions
diff --git a/src/lib/libcrypto/pkcs12/p12_key.c b/src/lib/libcrypto/pkcs12/p12_key.c index 38d25d2f6b..f85190aba9 100644 --- a/src/lib/libcrypto/pkcs12/p12_key.c +++ b/src/lib/libcrypto/pkcs12/p12_key.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: p12_key.c,v 1.28 2021/12/12 21:30:14 tb Exp $ */ | 1 | /* $OpenBSD: p12_key.c,v 1.29 2022/07/24 18:55:22 tb Exp $ */ |
| 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
| 3 | * project 1999. | 3 | * project 1999. |
| 4 | */ | 4 | */ |
| @@ -99,50 +99,58 @@ PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, | |||
| 99 | int saltlen, int id, int iter, int n, unsigned char *out, | 99 | int saltlen, int id, int iter, int n, unsigned char *out, |
| 100 | const EVP_MD *md_type) | 100 | const EVP_MD *md_type) |
| 101 | { | 101 | { |
| 102 | unsigned char *B, *D, *I, *p, *Ai; | 102 | EVP_MD_CTX *ctx = NULL; |
| 103 | int Slen, Plen, Ilen, Ijlen; | 103 | unsigned char *B = NULL, *D = NULL, *I = NULL, *Ai = NULL; |
| 104 | unsigned char *p; | ||
| 105 | int Slen, Plen, Ilen; | ||
| 104 | int i, j, u, v; | 106 | int i, j, u, v; |
| 105 | int ret = 0; | 107 | int ret = 0; |
| 106 | BIGNUM *Ij, *Bpl1; /* These hold Ij and B + 1 */ | ||
| 107 | EVP_MD_CTX ctx; | ||
| 108 | 108 | ||
| 109 | v = EVP_MD_block_size(md_type); | 109 | if ((ctx = EVP_MD_CTX_new()) == NULL) |
| 110 | u = EVP_MD_size(md_type); | 110 | goto err; |
| 111 | if (u < 0) | 111 | |
| 112 | return 0; | 112 | if ((v = EVP_MD_block_size(md_type)) <= 0) |
| 113 | goto err; | ||
| 114 | if ((u = EVP_MD_size(md_type)) <= 0) | ||
| 115 | goto err; | ||
| 116 | |||
| 117 | if ((D = malloc(v)) == NULL) | ||
| 118 | goto err; | ||
| 119 | if ((Ai = malloc(u)) == NULL) | ||
| 120 | goto err; | ||
| 121 | if ((B = malloc(v + 1)) == NULL) | ||
| 122 | goto err; | ||
| 113 | 123 | ||
| 114 | EVP_MD_CTX_init(&ctx); | ||
| 115 | D = malloc(v); | ||
| 116 | Ai = malloc(u); | ||
| 117 | B = malloc(v + 1); | ||
| 118 | Slen = v * ((saltlen + v - 1) / v); | 124 | Slen = v * ((saltlen + v - 1) / v); |
| 125 | |||
| 126 | Plen = 0; | ||
| 119 | if (passlen) | 127 | if (passlen) |
| 120 | Plen = v * ((passlen + v - 1)/v); | 128 | Plen = v * ((passlen + v - 1) / v); |
| 121 | else | 129 | |
| 122 | Plen = 0; | ||
| 123 | Ilen = Slen + Plen; | 130 | Ilen = Slen + Plen; |
| 124 | I = malloc(Ilen); | 131 | |
| 125 | Ij = BN_new(); | 132 | if ((I = malloc(Ilen)) == NULL) |
| 126 | Bpl1 = BN_new(); | ||
| 127 | if (!D || !Ai || !B || !I || !Ij || !Bpl1) | ||
| 128 | goto err; | 133 | goto err; |
| 134 | |||
| 129 | for (i = 0; i < v; i++) | 135 | for (i = 0; i < v; i++) |
| 130 | D[i] = id; | 136 | D[i] = id; |
| 137 | |||
| 131 | p = I; | 138 | p = I; |
| 132 | for (i = 0; i < Slen; i++) | 139 | for (i = 0; i < Slen; i++) |
| 133 | *p++ = salt[i % saltlen]; | 140 | *p++ = salt[i % saltlen]; |
| 134 | for (i = 0; i < Plen; i++) | 141 | for (i = 0; i < Plen; i++) |
| 135 | *p++ = pass[i % passlen]; | 142 | *p++ = pass[i % passlen]; |
| 143 | |||
| 136 | for (;;) { | 144 | for (;;) { |
| 137 | if (!EVP_DigestInit_ex(&ctx, md_type, NULL) || | 145 | if (!EVP_DigestInit_ex(ctx, md_type, NULL) || |
| 138 | !EVP_DigestUpdate(&ctx, D, v) || | 146 | !EVP_DigestUpdate(ctx, D, v) || |
| 139 | !EVP_DigestUpdate(&ctx, I, Ilen) || | 147 | !EVP_DigestUpdate(ctx, I, Ilen) || |
| 140 | !EVP_DigestFinal_ex(&ctx, Ai, NULL)) | 148 | !EVP_DigestFinal_ex(ctx, Ai, NULL)) |
| 141 | goto err; | 149 | goto err; |
| 142 | for (j = 1; j < iter; j++) { | 150 | for (j = 1; j < iter; j++) { |
| 143 | if (!EVP_DigestInit_ex(&ctx, md_type, NULL) || | 151 | if (!EVP_DigestInit_ex(ctx, md_type, NULL) || |
| 144 | !EVP_DigestUpdate(&ctx, Ai, u) || | 152 | !EVP_DigestUpdate(ctx, Ai, u) || |
| 145 | !EVP_DigestFinal_ex(&ctx, Ai, NULL)) | 153 | !EVP_DigestFinal_ex(ctx, Ai, NULL)) |
| 146 | goto err; | 154 | goto err; |
| 147 | } | 155 | } |
| 148 | memcpy(out, Ai, min(n, u)); | 156 | memcpy(out, Ai, min(n, u)); |
| @@ -154,46 +162,30 @@ PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, | |||
| 154 | out += u; | 162 | out += u; |
| 155 | for (j = 0; j < v; j++) | 163 | for (j = 0; j < v; j++) |
| 156 | B[j] = Ai[j % u]; | 164 | B[j] = Ai[j % u]; |
| 157 | /* Work out B + 1 first then can use B as tmp space */ | 165 | |
| 158 | if (!BN_bin2bn(B, v, Bpl1)) | ||
| 159 | goto err; | ||
| 160 | if (!BN_add_word(Bpl1, 1)) | ||
| 161 | goto err; | ||
| 162 | for (j = 0; j < Ilen; j += v) { | 166 | for (j = 0; j < Ilen; j += v) { |
| 163 | if (!BN_bin2bn(I + j, v, Ij)) | 167 | unsigned char *Ij = &I[j]; |
| 164 | goto err; | 168 | uint16_t c = 1; |
| 165 | if (!BN_add(Ij, Ij, Bpl1)) | 169 | int k; |
| 166 | goto err; | 170 | |
| 167 | if (!BN_bn2bin(Ij, B)) | 171 | /* Work out Ij = Ij + B + 1. */ |
| 168 | goto err; | 172 | for (k = v - 1; k >= 0; k--) { |
| 169 | Ijlen = BN_num_bytes(Ij); | 173 | c += Ij[k] + B[k]; |
| 170 | /* If more than 2^(v*8) - 1 cut off MSB */ | 174 | Ij[k] = (unsigned char)c; |
| 171 | if (Ijlen > v) { | 175 | c >>= 8; |
| 172 | if (!BN_bn2bin(Ij, B)) | 176 | } |
| 173 | goto err; | ||
| 174 | memcpy(I + j, B + 1, v); | ||
| 175 | #ifndef PKCS12_BROKEN_KEYGEN | ||
| 176 | /* If less than v bytes pad with zeroes */ | ||
| 177 | } else if (Ijlen < v) { | ||
| 178 | memset(I + j, 0, v - Ijlen); | ||
| 179 | if (!BN_bn2bin(Ij, I + j + v - Ijlen)) | ||
| 180 | goto err; | ||
| 181 | #endif | ||
| 182 | } else if (!BN_bn2bin(Ij, I + j)) | ||
| 183 | goto err; | ||
| 184 | } | 177 | } |
| 185 | } | 178 | } |
| 186 | 179 | ||
| 187 | err: | 180 | err: |
| 188 | PKCS12error(ERR_R_MALLOC_FAILURE); | 181 | PKCS12error(ERR_R_MALLOC_FAILURE); |
| 189 | 182 | ||
| 190 | end: | 183 | end: |
| 191 | free(Ai); | 184 | free(Ai); |
| 192 | free(B); | 185 | free(B); |
| 193 | free(D); | 186 | free(D); |
| 194 | free(I); | 187 | free(I); |
| 195 | BN_free(Ij); | 188 | EVP_MD_CTX_free(ctx); |
| 196 | BN_free(Bpl1); | 189 | |
| 197 | EVP_MD_CTX_cleanup(&ctx); | ||
| 198 | return ret; | 190 | return ret; |
| 199 | } | 191 | } |
