123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- #include <tinycrypt/hmac_prng.h>
- #include <tinycrypt/hmac.h>
- #include <tinycrypt/constants.h>
- #include <tinycrypt/utils.h>
- static const unsigned int MIN_SLEN = 32;
- static const unsigned int MAX_SLEN = UINT32_MAX;
- static const unsigned int MAX_PLEN = UINT32_MAX;
- static const unsigned int MAX_ALEN = UINT32_MAX;
- static const unsigned int MAX_GENS = UINT32_MAX;
- static const unsigned int MAX_OUT = (1 << 19);
- static void update(TCHmacPrng_t prng, const uint8_t *e, unsigned int len)
- {
- const uint8_t separator0 = 0x00;
- const uint8_t separator1 = 0x01;
-
- (void)tc_hmac_init(&prng->h);
- (void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v));
- (void)tc_hmac_update(&prng->h, &separator0, sizeof(separator0));
- (void)tc_hmac_update(&prng->h, e, len);
- (void)tc_hmac_final(prng->key, sizeof(prng->key), &prng->h);
-
- (void)tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key));
-
- (void)tc_hmac_init(&prng->h);
- (void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v));
- (void)tc_hmac_final(prng->v, sizeof(prng->v), &prng->h);
-
- (void)tc_hmac_init(&prng->h);
- (void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v));
- (void)tc_hmac_update(&prng->h, &separator1, sizeof(separator1));
- (void)tc_hmac_update(&prng->h, e, len);
- (void)tc_hmac_final(prng->key, sizeof(prng->key), &prng->h);
-
- (void)tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key));
-
- (void)tc_hmac_init(&prng->h);
- (void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v));
- (void)tc_hmac_final(prng->v, sizeof(prng->v), &prng->h);
- }
- int tc_hmac_prng_init(TCHmacPrng_t prng,
- const uint8_t *personalization,
- unsigned int plen)
- {
-
- if (prng == (TCHmacPrng_t) 0 ||
- personalization == (uint8_t *) 0 ||
- plen > MAX_PLEN) {
- return TC_CRYPTO_FAIL;
- }
-
- _set(prng->key, 0x00, sizeof(prng->key));
- _set(prng->v, 0x01, sizeof(prng->v));
- tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key));
-
- update(prng, personalization, plen);
-
- prng->countdown = 0;
- return TC_CRYPTO_SUCCESS;
- }
- int tc_hmac_prng_reseed(TCHmacPrng_t prng,
- const uint8_t *seed,
- unsigned int seedlen,
- const uint8_t *additional_input,
- unsigned int additionallen)
- {
-
- if (prng == (TCHmacPrng_t) 0 ||
- seed == (const uint8_t *) 0 ||
- seedlen < MIN_SLEN ||
- seedlen > MAX_SLEN) {
- return TC_CRYPTO_FAIL;
- }
- if (additional_input != (const uint8_t *) 0) {
-
- if (additionallen == 0 ||
- additionallen > MAX_ALEN) {
- return TC_CRYPTO_FAIL;
- } else {
-
- update(prng, seed, seedlen);
- update(prng, additional_input, additionallen);
- }
- } else {
-
- update(prng, seed, seedlen);
- }
-
- prng->countdown = MAX_GENS;
- return TC_CRYPTO_SUCCESS;
- }
- int tc_hmac_prng_generate(uint8_t *out, unsigned int outlen, TCHmacPrng_t prng)
- {
- unsigned int bufferlen;
-
- if (out == (uint8_t *) 0 ||
- prng == (TCHmacPrng_t) 0 ||
- outlen == 0 ||
- outlen > MAX_OUT) {
- return TC_CRYPTO_FAIL;
- } else if (prng->countdown == 0) {
- return TC_HMAC_PRNG_RESEED_REQ;
- }
- prng->countdown--;
- while (outlen != 0) {
-
- (void)tc_hmac_init(&prng->h);
- (void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v));
- (void)tc_hmac_final(prng->v, sizeof(prng->v), &prng->h);
- bufferlen = (TC_SHA256_DIGEST_SIZE > outlen) ?
- outlen : TC_SHA256_DIGEST_SIZE;
- (void)_copy(out, bufferlen, prng->v, bufferlen);
- out += bufferlen;
- outlen = (outlen > TC_SHA256_DIGEST_SIZE) ?
- (outlen - TC_SHA256_DIGEST_SIZE) : 0;
- }
-
- update(prng, prng->v, TC_SHA256_DIGEST_SIZE);
- return TC_CRYPTO_SUCCESS;
- }
|