2 * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
11 #include "internal/cryptlib.h"
12 #include <openssl/pkcs12.h>
13 #include <openssl/bn.h>
15 /* Uncomment out this line to get debugging info about key generation */
17 * #define OPENSSL_DEBUG_KEYGEN
19 #ifdef OPENSSL_DEBUG_KEYGEN
20 # include <openssl/bio.h>
22 void h__dump(unsigned char *p
, int len
);
25 /* PKCS12 compatible key/IV generation */
27 # define min(a,b) ((a) < (b) ? (a) : (b))
30 int PKCS12_key_gen_asc(const char *pass
, int passlen
, unsigned char *salt
,
31 int saltlen
, int id
, int iter
, int n
,
32 unsigned char *out
, const EVP_MD
*md_type
)
35 unsigned char *unipass
;
41 } else if (!OPENSSL_asc2uni(pass
, passlen
, &unipass
, &uniplen
)) {
42 PKCS12err(PKCS12_F_PKCS12_KEY_GEN_ASC
, ERR_R_MALLOC_FAILURE
);
45 ret
= PKCS12_key_gen_uni(unipass
, uniplen
, salt
, saltlen
,
46 id
, iter
, n
, out
, md_type
);
49 OPENSSL_clear_free(unipass
, uniplen
);
53 int PKCS12_key_gen_uni(unsigned char *pass
, int passlen
, unsigned char *salt
,
54 int saltlen
, int id
, int iter
, int n
,
55 unsigned char *out
, const EVP_MD
*md_type
)
57 unsigned char *B
= NULL
, *D
= NULL
, *I
= NULL
, *p
= NULL
, *Ai
= NULL
;
58 int Slen
, Plen
, Ilen
, Ijlen
;
61 BIGNUM
*Ij
= NULL
, *Bpl1
= NULL
; /* These hold Ij and B + 1 */
62 EVP_MD_CTX
*ctx
= NULL
;
63 #ifdef OPENSSL_DEBUG_KEYGEN
64 unsigned char *tmpout
= out
;
68 ctx
= EVP_MD_CTX_new();
72 #ifdef OPENSSL_DEBUG_KEYGEN
73 fprintf(stderr
, "KEYGEN DEBUG\n");
74 fprintf(stderr
, "ID %d, ITER %d\n", id
, iter
);
75 fprintf(stderr
, "Password (length %d):\n", passlen
);
76 h__dump(pass
, passlen
);
77 fprintf(stderr
, "Salt (length %d):\n", saltlen
);
78 h__dump(salt
, saltlen
);
80 v
= EVP_MD_block_size(md_type
);
81 u
= EVP_MD_size(md_type
);
84 D
= OPENSSL_malloc(v
);
85 Ai
= OPENSSL_malloc(u
);
86 B
= OPENSSL_malloc(v
+ 1);
87 Slen
= v
* ((saltlen
+ v
- 1) / v
);
89 Plen
= v
* ((passlen
+ v
- 1) / v
);
93 I
= OPENSSL_malloc(Ilen
);
96 if (D
== NULL
|| Ai
== NULL
|| B
== NULL
|| I
== NULL
|| Ij
== NULL
99 for (i
= 0; i
< v
; i
++)
102 for (i
= 0; i
< Slen
; i
++)
103 *p
++ = salt
[i
% saltlen
];
104 for (i
= 0; i
< Plen
; i
++)
105 *p
++ = pass
[i
% passlen
];
107 if (!EVP_DigestInit_ex(ctx
, md_type
, NULL
)
108 || !EVP_DigestUpdate(ctx
, D
, v
)
109 || !EVP_DigestUpdate(ctx
, I
, Ilen
)
110 || !EVP_DigestFinal_ex(ctx
, Ai
, NULL
))
112 for (j
= 1; j
< iter
; j
++) {
113 if (!EVP_DigestInit_ex(ctx
, md_type
, NULL
)
114 || !EVP_DigestUpdate(ctx
, Ai
, u
)
115 || !EVP_DigestFinal_ex(ctx
, Ai
, NULL
))
118 memcpy(out
, Ai
, min(n
, u
));
120 #ifdef OPENSSL_DEBUG_KEYGEN
121 fprintf(stderr
, "Output KEY (length %d)\n", tmpn
);
122 h__dump(tmpout
, tmpn
);
129 for (j
= 0; j
< v
; j
++)
131 /* Work out B + 1 first then can use B as tmp space */
132 if (!BN_bin2bn(B
, v
, Bpl1
))
134 if (!BN_add_word(Bpl1
, 1))
136 for (j
= 0; j
< Ilen
; j
+= v
) {
137 if (!BN_bin2bn(I
+ j
, v
, Ij
))
139 if (!BN_add(Ij
, Ij
, Bpl1
))
141 if (!BN_bn2bin(Ij
, B
))
143 Ijlen
= BN_num_bytes(Ij
);
144 /* If more than 2^(v*8) - 1 cut off MSB */
146 if (!BN_bn2bin(Ij
, B
))
148 memcpy(I
+ j
, B
+ 1, v
);
149 #ifndef PKCS12_BROKEN_KEYGEN
150 /* If less than v bytes pad with zeroes */
151 } else if (Ijlen
< v
) {
152 memset(I
+ j
, 0, v
- Ijlen
);
153 if (!BN_bn2bin(Ij
, I
+ j
+ v
- Ijlen
))
156 } else if (!BN_bn2bin(Ij
, I
+ j
))
162 PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI
, ERR_R_MALLOC_FAILURE
);
171 EVP_MD_CTX_free(ctx
);
175 #ifdef OPENSSL_DEBUG_KEYGEN
176 void h__dump(unsigned char *p
, int len
)
179 fprintf(stderr
, "%02X", *p
);
180 fprintf(stderr
, "\n");