1 #include "aes256ctr.h"
2 #include "aes.h"
3 #include <stddef.h>
4 #include <stdint.h>
5 #include <string.h>
6 
br_enc32be(unsigned char * dst,uint32_t x)7 static inline void br_enc32be(unsigned char *dst, uint32_t x) {
8     dst[3] = (unsigned char)x;
9     dst[2] = (unsigned char)(x >> 8);
10     dst[1] = (unsigned char)(x >> 16);
11     dst[0] = (unsigned char)(x >> 24);
12 }
13 
aes256_ctr_xof(unsigned char * out,size_t outlen,const unsigned char * iv,uint32_t ctr,const aes256ctx * ctx)14 static void aes256_ctr_xof(unsigned char *out, size_t outlen, const unsigned char *iv, uint32_t ctr, const aes256ctx *ctx) {
15     uint8_t ivw[16];
16     uint8_t buf[AES_BLOCKBYTES];
17 
18     memcpy(ivw, iv, AESCTR_NONCEBYTES);
19     br_enc32be(ivw + AESCTR_NONCEBYTES, ctr);
20 
21     while (outlen > AES_BLOCKBYTES) {
22         aes256_ecb(out, ivw, 1, ctx);
23         br_enc32be(ivw + AESCTR_NONCEBYTES, ++ctr);
24         out += AES_BLOCKBYTES;
25         outlen -= AES_BLOCKBYTES;
26     }
27     if (outlen > 0) {
28         aes256_ecb(buf, ivw, 1, ctx);
29         for (size_t i = 0; i < outlen; i++) {
30             out[i] = buf[i];
31         }
32     }
33 }
34 
35 /*************************************************
36 * Name:        aes256_prf
37 *
38 * Description: AES256 stream generation in CTR mode using 32-bit counter,
39 *              nonce is zero-padded to 12 bytes, counter starts at zero
40 *
41 * Arguments:   - uint8_t *output:      pointer to output
42 *              - size_t outlen:        length of requested output in bytes
43 *              - const uint8_t *key:   pointer to 32-byte key
44 *              - uint8_t nonce:        1-byte nonce (will be zero-padded to 12 bytes)
45 **************************************************/
PQCLEAN_KYBER51290S_CLEAN_aes256_prf(uint8_t * output,size_t outlen,const uint8_t * key,uint8_t nonce)46 void PQCLEAN_KYBER51290S_CLEAN_aes256_prf(uint8_t *output, size_t outlen, const uint8_t *key, uint8_t nonce) {
47     uint8_t iv[12];
48     for (int i = 1; i < 12; i++) {
49         iv[i] = 0;
50     }
51     iv[0] = nonce;
52 
53     aes256ctx ctx;
54     aes256_ctr_keyexp(&ctx, key);
55     aes256_ctr(output, outlen, iv, &ctx);
56     aes256_ctx_release(&ctx);
57 }
58 
59 /*************************************************
60 * Name:        aes256xof_absorb
61 *
62 * Description: AES256 CTR used as a replacement for a XOF; this function
63 *              "absorbs" a 32-byte key and two additional bytes that are zero-padded
64 *              to a 12-byte nonce
65 *
66 * Arguments:   - aes256xof_ctx *s:    pointer to state to "absorb" key and IV into
67 *              - const uint8_t *key:  pointer to 32-byte key
68 *              - uint8_t x:           first additional byte to "absorb"
69 *              - uint8_t y:           second additional byte to "absorb"
70 **************************************************/
PQCLEAN_KYBER51290S_CLEAN_aes256xof_absorb(aes256xof_ctx * s,const uint8_t * key,uint8_t x,uint8_t y)71 void PQCLEAN_KYBER51290S_CLEAN_aes256xof_absorb(aes256xof_ctx *s, const uint8_t *key, uint8_t x, uint8_t y) {
72     aes256_ecb_keyexp(&s->sk_exp, key);
73     for (int i = 2; i < 12; i++) {
74         s->iv[i] = 0;
75     }
76     s->iv[0] = x;
77     s->iv[1] = y;
78     s->ctr = 0;
79 }
80 
81 /*************************************************
82 * Name:        aes256xof_squeezeblocks
83 *
84 * Description: AES256 CTR used as a replacement for a XOF; this function
85 *              generates 4 blocks out AES256-CTR output
86 *
87 * Arguments:   - uint8_t *out:          pointer to output
88 *              - size_t nblocks:        number of reqested 64-byte output blocks
89 *              - aes256xof_ctx *s:      AES "state", i.e. expanded key and IV
90 **************************************************/
PQCLEAN_KYBER51290S_CLEAN_aes256xof_squeezeblocks(uint8_t * out,size_t nblocks,aes256xof_ctx * s)91 void PQCLEAN_KYBER51290S_CLEAN_aes256xof_squeezeblocks(uint8_t *out, size_t nblocks, aes256xof_ctx *s) {
92     aes256_ctr_xof(out, nblocks * 64, s->iv, s->ctr, &s->sk_exp);
93     s->ctr += (uint32_t) (4 * nblocks);
94 }
95 
96 /** Free the AES ctx **/
PQCLEAN_KYBER51290S_CLEAN_aes256xof_ctx_release(aes256xof_ctx * s)97 void PQCLEAN_KYBER51290S_CLEAN_aes256xof_ctx_release(aes256xof_ctx *s) {
98     aes256_ctx_release(&s->sk_exp);
99 }
100