1 /* 2 * Copyright (c) 2018 Thomas Pornin <pornin@bolet.org> 3 * 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: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 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 22 * SOFTWARE. 23 */ 24 25 #include "inner.h" 26 27 /* see bearssl_rand.h */ 28 void 29 br_aesctr_drbg_init(br_aesctr_drbg_context *ctx, 30 const br_block_ctr_class *aesctr, 31 const void *seed, size_t len) 32 { 33 unsigned char tmp[16]; 34 35 ctx->vtable = &br_aesctr_drbg_vtable; 36 memset(tmp, 0, sizeof tmp); 37 aesctr->init(&ctx->sk.vtable, tmp, 16); 38 ctx->cc = 0; 39 br_aesctr_drbg_update(ctx, seed, len); 40 } 41 42 /* see bearssl_rand.h */ 43 void 44 br_aesctr_drbg_generate(br_aesctr_drbg_context *ctx, void *out, size_t len) 45 { 46 unsigned char *buf; 47 unsigned char iv[12]; 48 49 buf = out; 50 memset(iv, 0, sizeof iv); 51 while (len > 0) { 52 size_t clen; 53 54 /* 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). 59 */ 60 clen = len; 61 if (clen > 65280) { 62 clen = 65280; 63 } 64 65 /* 66 * We make sure that the counter won't exceed the configured 67 * limit. 68 */ 69 if ((uint32_t)(ctx->cc + ((clen + 15) >> 4)) > 32768) { 70 clen = (32768 - ctx->cc) << 4; 71 if (clen > len) { 72 clen = len; 73 } 74 } 75 76 /* 77 * Run CTR. 78 */ 79 memset(buf, 0, clen); 80 ctx->cc = ctx->sk.vtable->run(&ctx->sk.vtable, 81 iv, ctx->cc, buf, clen); 82 buf += clen; 83 len -= clen; 84 85 /* 86 * Every 32768 blocks, we force a state update. 87 */ 88 if (ctx->cc >= 32768) { 89 br_aesctr_drbg_update(ctx, NULL, 0); 90 } 91 } 92 } 93 94 /* see bearssl_rand.h */ 95 void 96 br_aesctr_drbg_update(br_aesctr_drbg_context *ctx, const void *seed, size_t len) 97 { 98 /* 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 106 * G' = E(G) xor G 107 * H' = E(G xor C) xor G xor C 108 * G <- G', H <- H' 109 * - once all blocks have been processed, output is H||G 110 * 111 * Constants: 112 * G_init = B6 B6 ... B6 113 * H_init = A5 A5 ... A5 114 * C = 01 00 ... 00 115 * 116 * With this hash function h(), we compute the new state as 117 * follows: 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) 121 * 122 * Original Hirose article: 123 * https://www.iacr.org/archive/fse2006/40470213/40470213.pdf 124 */ 125 126 unsigned char s[16], iv[12]; 127 unsigned char G[16], H[16]; 128 int first; 129 130 /* 131 * Use an all-one IV to get a fresh output block that depends on the 132 * current seed. 133 */ 134 memset(iv, 0xFF, sizeof iv); 135 memset(s, 0, 16); 136 ctx->sk.vtable->run(&ctx->sk.vtable, iv, 0xFFFFFFFF, s, 16); 137 138 /* 139 * Set G[] and H[] to conventional start values. 140 */ 141 memset(G, 0xB6, sizeof G); 142 memset(H, 0x5A, sizeof H); 143 144 /* 145 * Process the concatenation of the current state and the seed 146 * with the custom hash function. 147 */ 148 first = 1; 149 for (;;) { 150 unsigned char tmp[32]; 151 unsigned char newG[16]; 152 153 /* 154 * Assemble new key H||m into tmp[]. 155 */ 156 memcpy(tmp, H, 16); 157 if (first) { 158 memcpy(tmp + 16, s, 16); 159 first = 0; 160 } else { 161 size_t clen; 162 163 if (len == 0) { 164 break; 165 } 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; 170 len -= clen; 171 } 172 ctx->sk.vtable->init(&ctx->sk.vtable, tmp, 32); 173 174 /* 175 * Compute new G and H values. 176 */ 177 memcpy(iv, G, 12); 178 memcpy(newG, G, 16); 179 ctx->sk.vtable->run(&ctx->sk.vtable, iv, 180 br_dec32be(G + 12), newG, 16); 181 iv[0] ^= 0x01; 182 memcpy(H, G, 16); 183 H[0] ^= 0x01; 184 ctx->sk.vtable->run(&ctx->sk.vtable, iv, 185 br_dec32be(G + 12), H, 16); 186 memcpy(G, newG, 16); 187 } 188 189 /* 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. 192 */ 193 ctx->sk.vtable->init(&ctx->sk.vtable, H, 16); 194 ctx->cc = 0; 195 } 196 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 206 }; 207