1 /* 2 * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. 3 * 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 8 */ 9 10 #include <stdio.h> 11 #include "internal/cryptlib.h" 12 #include <openssl/pkcs12.h> 13 #include <openssl/bn.h> 14 15 /* Uncomment out this line to get debugging info about key generation */ 16 /* 17 * #define OPENSSL_DEBUG_KEYGEN 18 */ 19 #ifdef OPENSSL_DEBUG_KEYGEN 20 # include <openssl/bio.h> 21 extern BIO *bio_err; 22 void h__dump(unsigned char *p, int len); 23 #endif 24 25 /* PKCS12 compatible key/IV generation */ 26 #ifndef min 27 # define min(a,b) ((a) < (b) ? (a) : (b)) 28 #endif 29 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) 33 { 34 int ret; 35 unsigned char *unipass; 36 int uniplen; 37 38 if (!pass) { 39 unipass = NULL; 40 uniplen = 0; 41 } else if (!OPENSSL_asc2uni(pass, passlen, &unipass, &uniplen)) { 42 PKCS12err(PKCS12_F_PKCS12_KEY_GEN_ASC, ERR_R_MALLOC_FAILURE); 43 return 0; 44 } 45 ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen, 46 id, iter, n, out, md_type); 47 if (ret <= 0) 48 return 0; 49 OPENSSL_clear_free(unipass, uniplen); 50 return ret; 51 } 52 53 int PKCS12_key_gen_utf8(const 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) 56 { 57 int ret; 58 unsigned char *unipass; 59 int uniplen; 60 61 if (!pass) { 62 unipass = NULL; 63 uniplen = 0; 64 } else if (!OPENSSL_utf82uni(pass, passlen, &unipass, &uniplen)) { 65 PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UTF8, ERR_R_MALLOC_FAILURE); 66 return 0; 67 } 68 ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen, 69 id, iter, n, out, md_type); 70 if (ret <= 0) 71 return 0; 72 OPENSSL_clear_free(unipass, uniplen); 73 return ret; 74 } 75 76 int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, 77 int saltlen, int id, int iter, int n, 78 unsigned char *out, const EVP_MD *md_type) 79 { 80 unsigned char *B = NULL, *D = NULL, *I = NULL, *p = NULL, *Ai = NULL; 81 int Slen, Plen, Ilen; 82 int i, j, u, v; 83 int ret = 0; 84 EVP_MD_CTX *ctx = NULL; 85 #ifdef OPENSSL_DEBUG_KEYGEN 86 unsigned char *tmpout = out; 87 int tmpn = n; 88 #endif 89 90 ctx = EVP_MD_CTX_new(); 91 if (ctx == NULL) 92 goto err; 93 94 #ifdef OPENSSL_DEBUG_KEYGEN 95 fprintf(stderr, "KEYGEN DEBUG\n"); 96 fprintf(stderr, "ID %d, ITER %d\n", id, iter); 97 fprintf(stderr, "Password (length %d):\n", passlen); 98 h__dump(pass, passlen); 99 fprintf(stderr, "Salt (length %d):\n", saltlen); 100 h__dump(salt, saltlen); 101 #endif 102 v = EVP_MD_block_size(md_type); 103 u = EVP_MD_size(md_type); 104 if (u < 0 || v <= 0) 105 goto err; 106 D = OPENSSL_malloc(v); 107 Ai = OPENSSL_malloc(u); 108 B = OPENSSL_malloc(v + 1); 109 Slen = v * ((saltlen + v - 1) / v); 110 if (passlen) 111 Plen = v * ((passlen + v - 1) / v); 112 else 113 Plen = 0; 114 Ilen = Slen + Plen; 115 I = OPENSSL_malloc(Ilen); 116 if (D == NULL || Ai == NULL || B == NULL || I == NULL) 117 goto err; 118 for (i = 0; i < v; i++) 119 D[i] = id; 120 p = I; 121 for (i = 0; i < Slen; i++) 122 *p++ = salt[i % saltlen]; 123 for (i = 0; i < Plen; i++) 124 *p++ = pass[i % passlen]; 125 for (;;) { 126 if (!EVP_DigestInit_ex(ctx, md_type, NULL) 127 || !EVP_DigestUpdate(ctx, D, v) 128 || !EVP_DigestUpdate(ctx, I, Ilen) 129 || !EVP_DigestFinal_ex(ctx, Ai, NULL)) 130 goto err; 131 for (j = 1; j < iter; j++) { 132 if (!EVP_DigestInit_ex(ctx, md_type, NULL) 133 || !EVP_DigestUpdate(ctx, Ai, u) 134 || !EVP_DigestFinal_ex(ctx, Ai, NULL)) 135 goto err; 136 } 137 memcpy(out, Ai, min(n, u)); 138 if (u >= n) { 139 #ifdef OPENSSL_DEBUG_KEYGEN 140 fprintf(stderr, "Output KEY (length %d)\n", tmpn); 141 h__dump(tmpout, tmpn); 142 #endif 143 ret = 1; 144 goto end; 145 } 146 n -= u; 147 out += u; 148 for (j = 0; j < v; j++) 149 B[j] = Ai[j % u]; 150 for (j = 0; j < Ilen; j += v) { 151 int k; 152 unsigned char *Ij = I + j; 153 uint16_t c = 1; 154 155 /* Work out Ij = Ij + B + 1 */ 156 for (k = v - 1; k >= 0; k--) { 157 c += Ij[k] + B[k]; 158 Ij[k] = (unsigned char)c; 159 c >>= 8; 160 } 161 } 162 } 163 164 err: 165 PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI, ERR_R_MALLOC_FAILURE); 166 167 end: 168 OPENSSL_free(Ai); 169 OPENSSL_free(B); 170 OPENSSL_free(D); 171 OPENSSL_free(I); 172 EVP_MD_CTX_free(ctx); 173 return ret; 174 } 175 176 #ifdef OPENSSL_DEBUG_KEYGEN 177 void h__dump(unsigned char *p, int len) 178 { 179 for (; len--; p++) 180 fprintf(stderr, "%02X", *p); 181 fprintf(stderr, "\n"); 182 } 183 #endif 184