2 * Copyright (c) 2018 Thomas Pornin <pornin@bolet.org>
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 /* see bearssl_rand.h */
29 br_aesctr_drbg_init(br_aesctr_drbg_context
*ctx
,
30 const br_block_ctr_class
*aesctr
,
31 const void *seed
, size_t len
)
33 unsigned char tmp
[16];
35 ctx
->vtable
= &br_aesctr_drbg_vtable
;
36 memset(tmp
, 0, sizeof tmp
);
37 aesctr
->init(&ctx
->sk
.vtable
, tmp
, 16);
39 br_aesctr_drbg_update(ctx
, seed
, len
);
42 /* see bearssl_rand.h */
44 br_aesctr_drbg_generate(br_aesctr_drbg_context
*ctx
, void *out
, size_t len
)
50 memset(iv
, 0, sizeof iv
);
55 * We generate data by blocks of at most 65280 bytes. This
56 * allows for unambiguously testing the counter overflow
57 * condition; also, it should work on 16-bit architectures
58 * (where 'size_t' is 16 bits only).
66 * We make sure that the counter won't exceed the configured
69 if ((uint32_t)(ctx
->cc
+ ((clen
+ 15) >> 4)) > 32768) {
70 clen
= (32768 - ctx
->cc
) << 4;
80 ctx
->cc
= ctx
->sk
.vtable
->run(&ctx
->sk
.vtable
,
81 iv
, ctx
->cc
, buf
, clen
);
86 * Every 32768 blocks, we force a state update.
88 if (ctx
->cc
>= 32768) {
89 br_aesctr_drbg_update(ctx
, NULL
, 0);
94 /* see bearssl_rand.h */
96 br_aesctr_drbg_update(br_aesctr_drbg_context
*ctx
, const void *seed
, size_t len
)
99 * We use a Hirose construction on AES-256 to make a hash function.
100 * Function definition:
101 * - running state consists in two 16-byte blocks G and H
102 * - initial values of G and H are conventional
103 * - there is a fixed block-sized constant C
104 * - for next data block m:
105 * set AES key to H||m
107 * H' = E(G xor C) xor G xor C
109 * - once all blocks have been processed, output is H||G
112 * G_init = B6 B6 ... B6
113 * H_init = A5 A5 ... A5
116 * With this hash function h(), we compute the new state as
118 * - produce a state-dependent value s as encryption of an
119 * all-one block with AES and the current key
120 * - compute the new key as the first 128 bits of h(s||seed)
122 * Original Hirose article:
123 * https://www.iacr.org/archive/fse2006/40470213/40470213.pdf
126 unsigned char s
[16], iv
[12];
127 unsigned char G
[16], H
[16];
131 * Use an all-one IV to get a fresh output block that depends on the
134 memset(iv
, 0xFF, sizeof iv
);
136 ctx
->sk
.vtable
->run(&ctx
->sk
.vtable
, iv
, 0xFFFFFFFF, s
, 16);
139 * Set G[] and H[] to conventional start values.
141 memset(G
, 0xB6, sizeof G
);
142 memset(H
, 0x5A, sizeof H
);
145 * Process the concatenation of the current state and the seed
146 * with the custom hash function.
150 unsigned char tmp
[32];
151 unsigned char newG
[16];
154 * Assemble new key H||m into tmp[].
158 memcpy(tmp
+ 16, s
, 16);
166 clen
= len
< 16 ? len
: 16;
167 memcpy(tmp
+ 16, seed
, clen
);
168 memset(tmp
+ 16 + clen
, 0, 16 - clen
);
169 seed
= (const unsigned char *)seed
+ clen
;
172 ctx
->sk
.vtable
->init(&ctx
->sk
.vtable
, tmp
, 32);
175 * Compute new G and H values.
179 ctx
->sk
.vtable
->run(&ctx
->sk
.vtable
, iv
,
180 br_dec32be(G
+ 12), newG
, 16);
184 ctx
->sk
.vtable
->run(&ctx
->sk
.vtable
, iv
,
185 br_dec32be(G
+ 12), H
, 16);
190 * Output hash value is H||G. We truncate it to its first 128 bits,
191 * i.e. H; that's our new AES key.
193 ctx
->sk
.vtable
->init(&ctx
->sk
.vtable
, H
, 16);
197 /* see bearssl_rand.h */
198 const br_prng_class br_aesctr_drbg_vtable
= {
199 sizeof(br_aesctr_drbg_context
),
200 (void (*)(const br_prng_class
**, const void *, const void *, size_t))
201 &br_aesctr_drbg_init
,
202 (void (*)(const br_prng_class
**, void *, size_t))
203 &br_aesctr_drbg_generate
,
204 (void (*)(const br_prng_class
**, const void *, size_t))
205 &br_aesctr_drbg_update