You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
164 lines
6.7 KiB
164 lines
6.7 KiB
/* hmac_prng.h - TinyCrypt interface to an HMAC-PRNG implementation */ |
|
|
|
/* |
|
* Copyright (C) 2017 by Intel Corporation, All Rights Reserved. |
|
* |
|
* Redistribution and use in source and binary forms, with or without |
|
* modification, are permitted provided that the following conditions are met: |
|
* |
|
* - Redistributions of source code must retain the above copyright notice, |
|
* this list of conditions and the following disclaimer. |
|
* |
|
* - Redistributions in binary form must reproduce the above copyright |
|
* notice, this list of conditions and the following disclaimer in the |
|
* documentation and/or other materials provided with the distribution. |
|
* |
|
* - Neither the name of Intel Corporation nor the names of its contributors |
|
* may be used to endorse or promote products derived from this software |
|
* without specific prior written permission. |
|
* |
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
* POSSIBILITY OF SUCH DAMAGE. |
|
*/ |
|
|
|
/** |
|
* @file |
|
* @brief Interface to an HMAC-PRNG implementation. |
|
* |
|
* Overview: A pseudo-random number generator (PRNG) generates a sequence |
|
* of numbers that have a distribution close to the one expected |
|
* for a sequence of truly random numbers. The NIST Special |
|
* Publication 800-90A specifies several mechanisms to generate |
|
* sequences of pseudo random numbers, including the HMAC-PRNG one |
|
* which is based on HMAC. TinyCrypt implements HMAC-PRNG with |
|
* certain modifications from the NIST SP 800-90A spec. |
|
* |
|
* Security: A cryptographically secure PRNG depends on the existence of an |
|
* entropy source to provide a truly random seed as well as the |
|
* security of the primitives used as the building blocks (HMAC and |
|
* SHA256, for TinyCrypt). |
|
* |
|
* The NIST SP 800-90A standard tolerates a null personalization, |
|
* while TinyCrypt requires a non-null personalization. This is |
|
* because a personalization string (the host name concatenated |
|
* with a time stamp, for example) is easily computed and might be |
|
* the last line of defense against failure of the entropy source. |
|
* |
|
* Requires: - SHA-256 |
|
* - HMAC |
|
* |
|
* Usage: 1) call tc_hmac_prng_init to set the HMAC key and process the |
|
* personalization data. |
|
* |
|
* 2) call tc_hmac_prng_reseed to process the seed and additional |
|
* input. |
|
* |
|
* 3) call tc_hmac_prng_generate to out put the pseudo-random data. |
|
*/ |
|
|
|
#ifndef __TC_HMAC_PRNG_H__ |
|
#define __TC_HMAC_PRNG_H__ |
|
|
|
#include <tinycrypt/sha256.h> |
|
#include <tinycrypt/hmac.h> |
|
|
|
#ifdef __cplusplus |
|
extern "C" { |
|
#endif |
|
|
|
#define TC_HMAC_PRNG_RESEED_REQ -1 |
|
|
|
struct tc_hmac_prng_struct { |
|
/* the HMAC instance for this PRNG */ |
|
struct tc_hmac_state_struct h; |
|
/* the PRNG key */ |
|
uint8_t key[TC_SHA256_DIGEST_SIZE]; |
|
/* PRNG state */ |
|
uint8_t v[TC_SHA256_DIGEST_SIZE]; |
|
/* calls to tc_hmac_prng_generate left before re-seed */ |
|
unsigned int countdown; |
|
}; |
|
|
|
typedef struct tc_hmac_prng_struct *TCHmacPrng_t; |
|
|
|
/** |
|
* @brief HMAC-PRNG initialization procedure |
|
* Initializes prng with personalization, disables tc_hmac_prng_generate |
|
* @return returns TC_CRYPTO_SUCCESS (1) |
|
* returns TC_CRYPTO_FAIL (0) if: |
|
* prng == NULL, |
|
* personalization == NULL, |
|
* plen > MAX_PLEN |
|
* @note Assumes: - personalization != NULL. |
|
* The personalization is a platform unique string (e.g., the host |
|
* name) and is the last line of defense against failure of the |
|
* entropy source |
|
* @warning NIST SP 800-90A specifies 3 items as seed material during |
|
* initialization: entropy seed, personalization, and an optional |
|
* nonce. TinyCrypts requires instead a non-null personalization |
|
* (which is easily computed) and indirectly requires an entropy |
|
* seed (since the reseed function is mandatorily called after |
|
* init) |
|
* @param prng IN/OUT -- the PRNG state to initialize |
|
* @param personalization IN -- personalization string |
|
* @param plen IN -- personalization length in bytes |
|
*/ |
|
int tc_hmac_prng_init(TCHmacPrng_t prng, |
|
const uint8_t *personalization, |
|
unsigned int plen); |
|
|
|
/** |
|
* @brief HMAC-PRNG reseed procedure |
|
* Mixes seed into prng, enables tc_hmac_prng_generate |
|
* @return returns TC_CRYPTO_SUCCESS (1) |
|
* returns TC_CRYPTO_FAIL (0) if: |
|
* prng == NULL, |
|
* seed == NULL, |
|
* seedlen < MIN_SLEN, |
|
* seendlen > MAX_SLEN, |
|
* additional_input != (const uint8_t *) 0 && additionallen == 0, |
|
* additional_input != (const uint8_t *) 0 && additionallen > MAX_ALEN |
|
* @note Assumes:- tc_hmac_prng_init has been called for prng |
|
* - seed has sufficient entropy. |
|
* |
|
* @param prng IN/OUT -- the PRNG state |
|
* @param seed IN -- entropy to mix into the prng |
|
* @param seedlen IN -- length of seed in bytes |
|
* @param additional_input IN -- additional input to the prng |
|
* @param additionallen IN -- additional input length in bytes |
|
*/ |
|
int tc_hmac_prng_reseed(TCHmacPrng_t prng, const uint8_t *seed, |
|
unsigned int seedlen, const uint8_t *additional_input, |
|
unsigned int additionallen); |
|
|
|
/** |
|
* @brief HMAC-PRNG generate procedure |
|
* Generates outlen pseudo-random bytes into out buffer, updates prng |
|
* @return returns TC_CRYPTO_SUCCESS (1) |
|
* returns TC_HMAC_PRNG_RESEED_REQ (-1) if a reseed is needed |
|
* returns TC_CRYPTO_FAIL (0) if: |
|
* out == NULL, |
|
* prng == NULL, |
|
* outlen == 0, |
|
* outlen >= MAX_OUT |
|
* @note Assumes tc_hmac_prng_init has been called for prng |
|
* @param out IN/OUT -- buffer to receive output |
|
* @param outlen IN -- size of out buffer in bytes |
|
* @param prng IN/OUT -- the PRNG state |
|
*/ |
|
int tc_hmac_prng_generate(uint8_t *out, unsigned int outlen, TCHmacPrng_t prng); |
|
|
|
#ifdef __cplusplus |
|
} |
|
#endif |
|
|
|
#endif /* __TC_HMAC_PRNG_H__ */
|
|
|