VirtualBox

source: vbox/trunk/src/libs/openssl-1.1.1l/crypto/pkcs12/p12_key.c@ 92405

Last change on this file since 92405 was 91772, checked in by vboxsync, 3 years ago

openssl-1.1.1l: Applied and adjusted our OpenSSL changes to 1.1.1l. bugref:10126

File size: 5.1 KB
Line 
1/*
2 * Copyright 1999-2021 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>
21extern BIO *bio_err;
22void 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
30int 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
53int 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
76int 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
177void h__dump(unsigned char *p, int len)
178{
179 for (; len--; p++)
180 fprintf(stderr, "%02X", *p);
181 fprintf(stderr, "\n");
182}
183#endif
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette