]>
git.ipfire.org Git - thirdparty/openssl.git/blob - fips/rand/fips_drbg_ctr.c
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/fips.h>
58 #include <openssl/fips_rand.h>
59 #include "fips_rand_lcl.h"
61 static void inc_128(DRBG_CTR_CTX
*cctx
)
65 unsigned char *p
= cctx
->V
+ 15;
66 for (i
= 0; i
< 16; i
++)
77 static void ctr_XOR(DRBG_CTR_CTX
*cctx
, const unsigned char *in
, size_t inlen
)
80 /* Any zero padding will have no effect on the result as we
81 * are XORing. So just process however much input we have.
87 if (inlen
< cctx
->keylen
)
92 for (i
= 0; i
< n
; i
++)
94 if (inlen
<= cctx
->keylen
)
97 n
= inlen
- cctx
->keylen
;
98 /* Should never happen */
101 for (i
= 0; i
< 16; i
++)
102 cctx
->V
[i
] ^= in
[i
+ cctx
->keylen
];
105 /* Process a complete block using BCC algorithm of SPP 800-90 10.4.3 */
107 static void ctr_BCC_block(DRBG_CTR_CTX
*cctx
, unsigned char *out
,
108 const unsigned char *in
)
111 for (i
= 0; i
< 16; i
++)
113 AES_encrypt(out
, out
, &cctx
->df_ks
);
115 fprintf(stderr
, "BCC in+out\n");
116 BIO_dump_fp(stderr
, in
, 16);
117 BIO_dump_fp(stderr
, out
, 16);
121 /* Handle several BCC operations for as much data as we need for K and X */
122 static void ctr_BCC_blocks(DRBG_CTR_CTX
*cctx
, const unsigned char *in
)
124 ctr_BCC_block(cctx
, cctx
->KX
, in
);
125 ctr_BCC_block(cctx
, cctx
->KX
+ 16, in
);
126 if (cctx
->keylen
!= 16)
127 ctr_BCC_block(cctx
, cctx
->KX
+ 32, in
);
129 /* Initialise BCC blocks: these have the value 0,1,2 in leftmost positions:
130 * see 10.4.2 stage 7.
132 static void ctr_BCC_init(DRBG_CTR_CTX
*cctx
)
134 memset(cctx
->KX
, 0, 48);
135 memset(cctx
->bltmp
, 0, 16);
136 ctr_BCC_block(cctx
, cctx
->KX
, cctx
->bltmp
);
138 ctr_BCC_block(cctx
, cctx
->KX
+ 16, cctx
->bltmp
);
139 if (cctx
->keylen
!= 16)
142 ctr_BCC_block(cctx
, cctx
->KX
+ 32, cctx
->bltmp
);
146 /* Process several blocks into BCC algorithm, some possibly partial */
147 static void ctr_BCC_update(DRBG_CTR_CTX
*cctx
,
148 const unsigned char *in
, size_t inlen
)
152 /* If we have partial block handle it first */
155 size_t left
= 16 - cctx
->bltmp_pos
;
156 /* If we now have a complete block process it */
159 memcpy(cctx
->bltmp
+ cctx
->bltmp_pos
, in
, left
);
160 ctr_BCC_blocks(cctx
, cctx
->bltmp
);
166 /* Process zero or more complete blocks */
169 ctr_BCC_blocks(cctx
, in
);
173 /* Copy any remaining partial block to the temporary buffer */
176 memcpy(cctx
->bltmp
+ cctx
->bltmp_pos
, in
, inlen
);
177 cctx
->bltmp_pos
+= inlen
;
181 static void ctr_BCC_final(DRBG_CTR_CTX
*cctx
)
185 memset(cctx
->bltmp
+ cctx
->bltmp_pos
, 0, 16 - cctx
->bltmp_pos
);
186 ctr_BCC_blocks(cctx
, cctx
->bltmp
);
190 static void ctr_df(DRBG_CTR_CTX
*cctx
,
191 const unsigned char *in1
, size_t in1len
,
192 const unsigned char *in2
, size_t in2len
,
193 const unsigned char *in3
, size_t in3len
)
196 unsigned char *p
= cctx
->bltmp
;
197 static unsigned char c80
= 0x80;
206 inlen
= in1len
+ in2len
+ in3len
;
207 /* Initialise L||N in temporary block */
208 *p
++ = (inlen
>> 24) & 0xff;
209 *p
++ = (inlen
>> 16) & 0xff;
210 *p
++ = (inlen
>> 8) & 0xff;
212 /* NB keylen is at most 32 bytes */
216 *p
= (unsigned char)((cctx
->keylen
+ 16) & 0xff);
218 ctr_BCC_update(cctx
, in1
, in1len
);
219 ctr_BCC_update(cctx
, in2
, in2len
);
220 ctr_BCC_update(cctx
, in3
, in3len
);
221 ctr_BCC_update(cctx
, &c80
, 1);
224 AES_set_encrypt_key(cctx
->KX
, cctx
->keylen
* 8, &cctx
->df_kxks
);
225 /* X follows key K */
226 AES_encrypt(cctx
->KX
+ cctx
->keylen
, cctx
->KX
, &cctx
->df_kxks
);
227 AES_encrypt(cctx
->KX
, cctx
->KX
+ 16, &cctx
->df_kxks
);
228 if (cctx
->keylen
!= 16)
229 AES_encrypt(cctx
->KX
+ 16, cctx
->KX
+ 32, &cctx
->df_kxks
);
231 fprintf(stderr
, "Output of ctr_df:\n");
232 BIO_dump_fp(stderr
, cctx
->KX
, cctx
->keylen
+ 16);
236 /* NB the no-df Update in SP800-90 specifies a constant input length
237 * of seedlen, however other uses of this algorithm pad the input with
238 * zeroes if necessary and have up to two parameters XORed together,
239 * handle both cases in this function instead.
242 static void ctr_Update(DRBG_CTX
*dctx
,
243 const unsigned char *in1
, size_t in1len
,
244 const unsigned char *in2
, size_t in2len
,
245 const unsigned char *nonce
, size_t noncelen
)
247 DRBG_CTR_CTX
*cctx
= &dctx
->d
.ctr
;
248 /* ks is already setup for correct key */
250 AES_encrypt(cctx
->V
, cctx
->K
, &cctx
->ks
);
251 /* If keylen longer than 128 bits need extra encrypt */
252 if (cctx
->keylen
!= 16)
255 AES_encrypt(cctx
->V
, cctx
->K
+ 16, &cctx
->ks
);
258 AES_encrypt(cctx
->V
, cctx
->V
, &cctx
->ks
);
259 /* If 192 bit key part of V is on end of K */
260 if (cctx
->keylen
== 24)
262 memcpy(cctx
->V
+ 8, cctx
->V
, 8);
263 memcpy(cctx
->V
, cctx
->K
+ 24, 8);
266 if (dctx
->xflags
& DRBG_FLAG_CTR_USE_DF
)
268 /* If no input reuse existing derived value */
269 if (in1
|| nonce
|| in2
)
270 ctr_df(cctx
, in1
, in1len
, nonce
, noncelen
, in2
, in2len
);
271 /* If this a reuse input in1len != 0 */
273 ctr_XOR(cctx
, cctx
->KX
, dctx
->seedlen
);
277 ctr_XOR(cctx
, in1
, in1len
);
278 ctr_XOR(cctx
, in2
, in2len
);
281 AES_set_encrypt_key(cctx
->K
, dctx
->strength
, &cctx
->ks
);
283 fprintf(stderr
, "K+V after update is:\n");
284 BIO_dump_fp(stderr
, cctx
->K
, cctx
->keylen
);
285 BIO_dump_fp(stderr
, cctx
->V
, 16);
289 static int drbg_ctr_instantiate(DRBG_CTX
*dctx
,
290 const unsigned char *ent
, size_t entlen
,
291 const unsigned char *nonce
, size_t noncelen
,
292 const unsigned char *pers
, size_t perslen
)
294 DRBG_CTR_CTX
*cctx
= &dctx
->d
.ctr
;
295 memset(cctx
->K
, 0, sizeof(cctx
->K
));
296 memset(cctx
->V
, 0, sizeof(cctx
->V
));
297 AES_set_encrypt_key(cctx
->K
, dctx
->strength
, &cctx
->ks
);
298 ctr_Update(dctx
, ent
, entlen
, pers
, perslen
, nonce
, noncelen
);
302 static int drbg_ctr_reseed(DRBG_CTX
*dctx
,
303 const unsigned char *ent
, size_t entlen
,
304 const unsigned char *adin
, size_t adinlen
)
306 ctr_Update(dctx
, ent
, entlen
, adin
, adinlen
, NULL
, 0);
310 static int drbg_ctr_generate(DRBG_CTX
*dctx
,
311 unsigned char *out
, size_t outlen
,
312 const unsigned char *adin
, size_t adinlen
)
314 DRBG_CTR_CTX
*cctx
= &dctx
->d
.ctr
;
317 ctr_Update(dctx
, adin
, adinlen
, NULL
, 0, NULL
, 0);
318 /* This means we reuse derived value */
319 if (dctx
->xflags
& DRBG_FLAG_CTR_USE_DF
)
331 if (!(dctx
->xflags
& DRBG_FLAG_TEST
) && !dctx
->lb_valid
)
333 AES_encrypt(cctx
->V
, dctx
->lb
, &cctx
->ks
);
339 /* Use K as temp space as it will be updated */
340 AES_encrypt(cctx
->V
, cctx
->K
, &cctx
->ks
);
341 if (!fips_drbg_cprng_test(dctx
, cctx
->K
))
343 memcpy(out
, cctx
->K
, outlen
);
346 AES_encrypt(cctx
->V
, out
, &cctx
->ks
);
347 if (!fips_drbg_cprng_test(dctx
, out
))
355 ctr_Update(dctx
, adin
, adinlen
, NULL
, 0, NULL
, 0);
361 static int drbg_ctr_uninstantiate(DRBG_CTX
*dctx
)
363 memset(&dctx
->d
.ctr
, 0, sizeof(DRBG_CTR_CTX
));
367 int fips_drbg_ctr_init(DRBG_CTX
*dctx
)
369 DRBG_CTR_CTX
*cctx
= &dctx
->d
.ctr
;
375 case NID_aes_128_ctr
:
379 case NID_aes_192_ctr
:
383 case NID_aes_256_ctr
:
391 dctx
->instantiate
= drbg_ctr_instantiate
;
392 dctx
->reseed
= drbg_ctr_reseed
;
393 dctx
->generate
= drbg_ctr_generate
;
394 dctx
->uninstantiate
= drbg_ctr_uninstantiate
;
396 cctx
->keylen
= keylen
;
397 dctx
->strength
= keylen
* 8;
398 dctx
->blocklength
= 16;
399 dctx
->seedlen
= keylen
+ 16;
401 if (dctx
->xflags
& DRBG_FLAG_CTR_USE_DF
)
403 /* df initialisation */
404 static unsigned char df_key
[32] =
406 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
407 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
408 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
409 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f
411 /* Set key schedule for df_key */
412 AES_set_encrypt_key(df_key
, dctx
->strength
, &cctx
->df_ks
);
414 dctx
->min_entropy
= cctx
->keylen
;
415 dctx
->max_entropy
= DRBG_MAX_LENGTH
;
416 dctx
->min_nonce
= dctx
->min_entropy
/ 2;
417 dctx
->max_nonce
= DRBG_MAX_LENGTH
;
418 dctx
->max_pers
= DRBG_MAX_LENGTH
;
419 dctx
->max_adin
= DRBG_MAX_LENGTH
;
423 dctx
->min_entropy
= dctx
->seedlen
;
424 dctx
->max_entropy
= dctx
->seedlen
;
428 dctx
->max_pers
= dctx
->seedlen
;
429 dctx
->max_adin
= dctx
->seedlen
;
432 dctx
->max_request
= 1<<16;
433 dctx
->reseed_interval
= 1<<24;