1 /* fips/rand/fips_drbg_hmac.c */
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
5 /* ====================================================================
6 * Copyright (c) 2011 The OpenSSL Project. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
34 * 6. Redistributions of any form whatsoever must retain the following
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
56 #include <openssl/crypto.h>
57 #include <openssl/evp.h>
58 #include <openssl/hmac.h>
59 #include <openssl/aes.h>
60 #include <openssl/fips.h>
61 #include <openssl/fips_rand.h>
62 #include "fips_rand_lcl.h"
64 static int drbg_hmac_update(DRBG_CTX *dctx,
65 const unsigned char *in1, size_t in1len,
66 const unsigned char *in2, size_t in2len,
67 const unsigned char *in3, size_t in3len
70 static unsigned char c0 = 0, c1 = 1;
71 DRBG_HMAC_CTX *hmac = &dctx->d.hmac;
72 HMAC_CTX *hctx = &hmac->hctx;
74 if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength, hmac->md, NULL))
76 if (!HMAC_Update(hctx, hmac->V, dctx->blocklength))
78 if (!HMAC_Update(hctx, &c0, 1))
80 if (in1len && !HMAC_Update(hctx, in1, in1len))
82 if (in2len && !HMAC_Update(hctx, in2, in2len))
84 if (in3len && !HMAC_Update(hctx, in3, in3len))
87 if (!HMAC_Final(hctx, hmac->K, NULL))
90 if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength, hmac->md, NULL))
92 if (!HMAC_Update(hctx, hmac->V, dctx->blocklength))
95 if (!HMAC_Final(hctx, hmac->V, NULL))
98 if (!in1len && !in2len && !in3len)
101 if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength, hmac->md, NULL))
103 if (!HMAC_Update(hctx, hmac->V, dctx->blocklength))
105 if (!HMAC_Update(hctx, &c1, 1))
107 if (in1len && !HMAC_Update(hctx, in1, in1len))
109 if (in2len && !HMAC_Update(hctx, in2, in2len))
111 if (in3len && !HMAC_Update(hctx, in3, in3len))
114 if (!HMAC_Final(hctx, hmac->K, NULL))
117 if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength, hmac->md, NULL))
119 if (!HMAC_Update(hctx, hmac->V, dctx->blocklength))
122 if (!HMAC_Final(hctx, hmac->V, NULL))
129 static int drbg_hmac_instantiate(DRBG_CTX *dctx,
130 const unsigned char *ent, size_t ent_len,
131 const unsigned char *nonce, size_t nonce_len,
132 const unsigned char *pstr, size_t pstr_len)
134 DRBG_HMAC_CTX *hmac = &dctx->d.hmac;
135 memset(hmac->K, 0, dctx->blocklength);
136 memset(hmac->V, 1, dctx->blocklength);
137 if (!drbg_hmac_update(dctx,
138 ent, ent_len, nonce, nonce_len, pstr, pstr_len))
141 #ifdef HMAC_DRBG_TRACE
142 fprintf(stderr, "K+V after instantiate:\n");
143 hexprint(stderr, hmac->K, hmac->blocklength);
144 hexprint(stderr, hmac->V, hmac->blocklength);
149 static int drbg_hmac_reseed(DRBG_CTX *dctx,
150 const unsigned char *ent, size_t ent_len,
151 const unsigned char *adin, size_t adin_len)
153 if (!drbg_hmac_update(dctx,
154 ent, ent_len, adin, adin_len, NULL, 0))
157 #ifdef HMAC_DRBG_TRACE
159 DRBG_HMAC_CTX *hmac = &dctx->d.hmac;
160 fprintf(stderr, "K+V after reseed:\n");
161 hexprint(stderr, hmac->K, hmac->blocklength);
162 hexprint(stderr, hmac->V, hmac->blocklength);
168 static int drbg_hmac_generate(DRBG_CTX *dctx,
169 unsigned char *out, size_t outlen,
170 const unsigned char *adin, size_t adin_len)
172 DRBG_HMAC_CTX *hmac = &dctx->d.hmac;
173 HMAC_CTX *hctx = &hmac->hctx;
174 const unsigned char *Vtmp = hmac->V;
175 if (adin_len && !drbg_hmac_update(dctx, adin, adin_len,
180 if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength,
183 if (!HMAC_Update(hctx, Vtmp, dctx->blocklength))
185 if (!(dctx->xflags & DRBG_FLAG_TEST) && !dctx->lb_valid)
187 if (!HMAC_Final(hctx, dctx->lb, NULL))
193 else if (outlen > dctx->blocklength)
195 if (!HMAC_Final(hctx, out, NULL))
197 if (!fips_drbg_cprng_test(dctx, out))
203 if (!HMAC_Final(hctx, hmac->V, NULL))
205 if (!fips_drbg_cprng_test(dctx, hmac->V))
207 memcpy(out, hmac->V, outlen);
210 out += dctx->blocklength;
211 outlen -= dctx->blocklength;
213 if (!drbg_hmac_update(dctx, adin, adin_len, NULL, 0, NULL, 0))
219 static int drbg_hmac_uninstantiate(DRBG_CTX *dctx)
221 HMAC_CTX_cleanup(&dctx->d.hmac.hctx);
222 OPENSSL_cleanse(&dctx->d.hmac, sizeof(DRBG_HMAC_CTX));
226 int fips_drbg_hmac_init(DRBG_CTX *dctx)
228 const EVP_MD *md = NULL;
229 DRBG_HMAC_CTX *hctx = &dctx->d.hmac;
230 dctx->strength = 256;
233 case NID_hmacWithSHA1:
235 dctx->strength = 128;
238 case NID_hmacWithSHA224:
240 dctx->strength = 192;
243 case NID_hmacWithSHA256:
247 case NID_hmacWithSHA384:
251 case NID_hmacWithSHA512:
259 dctx->instantiate = drbg_hmac_instantiate;
260 dctx->reseed = drbg_hmac_reseed;
261 dctx->generate = drbg_hmac_generate;
262 dctx->uninstantiate = drbg_hmac_uninstantiate;
263 HMAC_CTX_init(&hctx->hctx);
265 dctx->blocklength = M_EVP_MD_size(md);
266 dctx->seedlen = M_EVP_MD_size(md);
268 dctx->min_entropy = dctx->strength / 8;
269 dctx->max_entropy = DRBG_MAX_LENGTH;
271 dctx->min_nonce = dctx->min_entropy / 2;
272 dctx->max_nonce = DRBG_MAX_LENGTH;
274 dctx->max_pers = DRBG_MAX_LENGTH;
275 dctx->max_adin = DRBG_MAX_LENGTH;
277 dctx->max_request = 1<<16;
278 dctx->reseed_interval = 1<<24;