1 /* fips/rand/fips_drbg_ctr.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/aes.h>
59 #include <openssl/fips.h>
60 #include <openssl/fips_rand.h>
61 #include "fips_rand_lcl.h"
63 static void inc_128(DRBG_CTR_CTX *cctx)
67 unsigned char *p = cctx->V + 15;
68 for (i = 0; i < 16; i++)
79 static void ctr_XOR(DRBG_CTR_CTX *cctx, const unsigned char *in, size_t inlen)
82 /* Any zero padding will have no effect on the result as we
83 * are XORing. So just process however much input we have.
89 if (inlen < cctx->keylen)
94 for (i = 0; i < n; i++)
96 if (inlen <= cctx->keylen)
99 n = inlen - cctx->keylen;
100 /* Should never happen */
103 for (i = 0; i < 16; i++)
104 cctx->V[i] ^= in[i + cctx->keylen];
107 /* Process a complete block using BCC algorithm of SPP 800-90 10.4.3 */
109 static void ctr_BCC_block(DRBG_CTR_CTX *cctx, unsigned char *out,
110 const unsigned char *in)
113 for (i = 0; i < 16; i++)
115 AES_encrypt(out, out, &cctx->df_ks);
117 fprintf(stderr, "BCC in+out\n");
118 BIO_dump_fp(stderr, in, 16);
119 BIO_dump_fp(stderr, out, 16);
123 /* Handle several BCC operations for as much data as we need for K and X */
124 static void ctr_BCC_blocks(DRBG_CTR_CTX *cctx, const unsigned char *in)
126 ctr_BCC_block(cctx, cctx->KX, in);
127 ctr_BCC_block(cctx, cctx->KX + 16, in);
128 if (cctx->keylen != 16)
129 ctr_BCC_block(cctx, cctx->KX + 32, in);
131 /* Initialise BCC blocks: these have the value 0,1,2 in leftmost positions:
132 * see 10.4.2 stage 7.
134 static void ctr_BCC_init(DRBG_CTR_CTX *cctx)
136 memset(cctx->KX, 0, 48);
137 memset(cctx->bltmp, 0, 16);
138 ctr_BCC_block(cctx, cctx->KX, cctx->bltmp);
140 ctr_BCC_block(cctx, cctx->KX + 16, cctx->bltmp);
141 if (cctx->keylen != 16)
144 ctr_BCC_block(cctx, cctx->KX + 32, cctx->bltmp);
148 /* Process several blocks into BCC algorithm, some possibly partial */
149 static void ctr_BCC_update(DRBG_CTR_CTX *cctx,
150 const unsigned char *in, size_t inlen)
154 /* If we have partial block handle it first */
157 size_t left = 16 - cctx->bltmp_pos;
158 /* If we now have a complete block process it */
161 memcpy(cctx->bltmp + cctx->bltmp_pos, in, left);
162 ctr_BCC_blocks(cctx, cctx->bltmp);
168 /* Process zero or more complete blocks */
171 ctr_BCC_blocks(cctx, in);
175 /* Copy any remaining partial block to the temporary buffer */
178 memcpy(cctx->bltmp + cctx->bltmp_pos, in, inlen);
179 cctx->bltmp_pos += inlen;
183 static void ctr_BCC_final(DRBG_CTR_CTX *cctx)
187 memset(cctx->bltmp + cctx->bltmp_pos, 0, 16 - cctx->bltmp_pos);
188 ctr_BCC_blocks(cctx, cctx->bltmp);
192 static void ctr_df(DRBG_CTR_CTX *cctx,
193 const unsigned char *in1, size_t in1len,
194 const unsigned char *in2, size_t in2len,
195 const unsigned char *in3, size_t in3len)
198 unsigned char *p = cctx->bltmp;
199 static unsigned char c80 = 0x80;
208 inlen = in1len + in2len + in3len;
209 /* Initialise L||N in temporary block */
210 *p++ = (inlen >> 24) & 0xff;
211 *p++ = (inlen >> 16) & 0xff;
212 *p++ = (inlen >> 8) & 0xff;
214 /* NB keylen is at most 32 bytes */
218 *p = (unsigned char)((cctx->keylen + 16) & 0xff);
220 ctr_BCC_update(cctx, in1, in1len);
221 ctr_BCC_update(cctx, in2, in2len);
222 ctr_BCC_update(cctx, in3, in3len);
223 ctr_BCC_update(cctx, &c80, 1);
226 AES_set_encrypt_key(cctx->KX, cctx->keylen * 8, &cctx->df_kxks);
227 /* X follows key K */
228 AES_encrypt(cctx->KX + cctx->keylen, cctx->KX, &cctx->df_kxks);
229 AES_encrypt(cctx->KX, cctx->KX + 16, &cctx->df_kxks);
230 if (cctx->keylen != 16)
231 AES_encrypt(cctx->KX + 16, cctx->KX + 32, &cctx->df_kxks);
233 fprintf(stderr, "Output of ctr_df:\n");
234 BIO_dump_fp(stderr, cctx->KX, cctx->keylen + 16);
238 /* NB the no-df Update in SP800-90 specifies a constant input length
239 * of seedlen, however other uses of this algorithm pad the input with
240 * zeroes if necessary and have up to two parameters XORed together,
241 * handle both cases in this function instead.
244 static void ctr_Update(DRBG_CTX *dctx,
245 const unsigned char *in1, size_t in1len,
246 const unsigned char *in2, size_t in2len,
247 const unsigned char *nonce, size_t noncelen)
249 DRBG_CTR_CTX *cctx = &dctx->d.ctr;
250 /* ks is already setup for correct key */
252 AES_encrypt(cctx->V, cctx->K, &cctx->ks);
253 /* If keylen longer than 128 bits need extra encrypt */
254 if (cctx->keylen != 16)
257 AES_encrypt(cctx->V, cctx->K + 16, &cctx->ks);
260 AES_encrypt(cctx->V, cctx->V, &cctx->ks);
261 /* If 192 bit key part of V is on end of K */
262 if (cctx->keylen == 24)
264 memcpy(cctx->V + 8, cctx->V, 8);
265 memcpy(cctx->V, cctx->K + 24, 8);
268 if (dctx->flags & DRBG_FLAG_CTR_USE_DF)
270 /* If no input reuse existing derived value */
271 if (in1 || nonce || in2)
272 ctr_df(cctx, in1, in1len, nonce, noncelen, in2, in2len);
273 /* If this a reuse input in1len != 0 */
275 ctr_XOR(cctx, cctx->KX, dctx->seedlen);
279 ctr_XOR(cctx, in1, in1len);
280 ctr_XOR(cctx, in2, in2len);
283 AES_set_encrypt_key(cctx->K, dctx->strength, &cctx->ks);
285 fprintf(stderr, "K+V after update is:\n");
286 BIO_dump_fp(stderr, cctx->K, cctx->keylen);
287 BIO_dump_fp(stderr, cctx->V, 16);
291 static int drbg_ctr_instantiate(DRBG_CTX *dctx,
292 const unsigned char *ent, size_t entlen,
293 const unsigned char *nonce, size_t noncelen,
294 const unsigned char *pers, size_t perslen)
296 DRBG_CTR_CTX *cctx = &dctx->d.ctr;
297 memset(cctx->K, 0, sizeof(cctx->K));
298 memset(cctx->V, 0, sizeof(cctx->V));
299 AES_set_encrypt_key(cctx->K, dctx->strength, &cctx->ks);
300 ctr_Update(dctx, ent, entlen, pers, perslen, nonce, noncelen);
304 static int drbg_ctr_reseed(DRBG_CTX *dctx,
305 const unsigned char *ent, size_t entlen,
306 const unsigned char *adin, size_t adinlen)
308 ctr_Update(dctx, ent, entlen, adin, adinlen, NULL, 0);
312 static int drbg_ctr_generate(DRBG_CTX *dctx,
313 unsigned char *out, size_t outlen,
314 const unsigned char *adin, size_t adinlen)
316 DRBG_CTR_CTX *cctx = &dctx->d.ctr;
319 ctr_Update(dctx, adin, adinlen, NULL, 0, NULL, 0);
320 /* This means we reuse derived value */
321 if (dctx->flags & DRBG_FLAG_CTR_USE_DF)
335 /* Use K as temp space as it will be updated */
336 AES_encrypt(cctx->V, cctx->K, &cctx->ks);
337 memcpy(out, cctx->K, outlen);
340 AES_encrypt(cctx->V, out, &cctx->ks);
347 ctr_Update(dctx, adin, adinlen, NULL, 0, NULL, 0);
353 static int drbg_ctr_uninstantiate(DRBG_CTX *dctx)
355 memset(&dctx->d.ctr, 0, sizeof(DRBG_CTR_CTX));
359 int fips_drbg_ctr_init(DRBG_CTX *dctx)
361 DRBG_CTR_CTX *cctx = &dctx->d.ctr;
367 case NID_aes_128_ctr:
371 case NID_aes_192_ctr:
375 case NID_aes_256_ctr:
383 dctx->instantiate = drbg_ctr_instantiate;
384 dctx->reseed = drbg_ctr_reseed;
385 dctx->generate = drbg_ctr_generate;
386 dctx->uninstantiate = drbg_ctr_uninstantiate;
388 cctx->keylen = keylen;
389 dctx->strength = keylen * 8;
390 dctx->blocklength = 16;
391 dctx->seedlen = keylen + 16;
393 if (dctx->flags & DRBG_FLAG_CTR_USE_DF)
395 /* df initialisation */
396 static unsigned char df_key[32] =
398 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
399 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
400 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
401 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f
403 /* Set key schedule for df_key */
404 AES_set_encrypt_key(df_key, dctx->strength, &cctx->df_ks);
406 dctx->min_entropy = cctx->keylen;
407 dctx->max_entropy = DRBG_MAX_ENTROPY;
408 dctx->min_nonce = dctx->min_entropy / 2;
409 dctx->max_nonce = DRBG_MAX_NONCE;
410 dctx->max_pers = DRBG_MAX_LENGTH;
411 dctx->max_adin = DRBG_MAX_LENGTH;
415 dctx->min_entropy = dctx->seedlen;
416 dctx->max_entropy = dctx->seedlen;
420 dctx->max_pers = dctx->seedlen;
421 dctx->max_adin = dctx->seedlen;
424 dctx->max_request = 1<<19;
425 dctx->reseed_interval = 1<<24;