diff options
author | Flavio Santes <flavio.santes@intel.com> | 2016-07-24 23:52:50 -0500 |
---|---|---|
committer | Andrew Boie <andrew.p.boie@intel.com> | 2016-07-27 21:33:42 +0000 |
commit | e6ffc0ed289acf8aab11bc7b9aa5803d378e5159 (patch) | |
tree | 5ef5602efb2d209fcc282bf9f4d4dc782f574f7d /ext | |
parent | a52f8dcbeec8c1b8231048f4af90392ca282d151 (diff) |
crypto: Update tinycrypt source files
Update Zephyr's tinycrypt to version 2.0. This new version adds support
for ECC_DH, ECC_DSA, CMAC, & CTR_PRNG.
The following doxygen documentation typos were detected and fixed:
- ctr_prng.h:84 change plen by pLen,
- ctr_prng.h:109 change entropylen by entropyLen,
- sha256.h:110 change Sha256 by s.
ecc_dh.h is also modified to fix the discrepancy of ecc_make_key
definition and declaration.
See https://gerrit.zephyrproject.org/r/#/c/1982/
TC_FAIL and TC_SUCCESS defines are renamed in this new version of
tinycrypt, so net/bluetooth/hci_core.c, net/bluetooth/hci_ecc.c and
net/bluetooth/smp.c are also updated to reflect those changes.
Origin: https://github.com/01org/tinycrypt/archive/v0.2.0.tar.gz
Jira: ZEP-590
Change-Id: I85f4f0ab61d9b0be6a60897e2b96f245dd8c51a8
Signed-off-by: Flavio Santes <flavio.santes@intel.com>
Diffstat (limited to 'ext')
24 files changed, 608 insertions, 137 deletions
diff --git a/ext/lib/crypto/tinycrypt/include/tinycrypt/aes.h b/ext/lib/crypto/tinycrypt/include/tinycrypt/aes.h index c6fcc96c6..b6dbbb54f 100644 --- a/ext/lib/crypto/tinycrypt/include/tinycrypt/aes.h +++ b/ext/lib/crypto/tinycrypt/include/tinycrypt/aes.h @@ -69,8 +69,8 @@ typedef struct tc_aes_key_sched_struct *TCAesKeySched_t; /** * @brief Set AES-128 encryption key * Uses key k to initialize s - * @return returns TC_SUCCESS (1) - * returns TC_FAIL (0) if: s == NULL or k == NULL + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: s == NULL or k == NULL * @note This implementation skips the additional steps required for keys * larger than 128 bits, and must not be used for AES-192 or * AES-256 key schedule -- see FIPS 197 for details @@ -85,8 +85,8 @@ int32_t tc_aes128_set_encrypt_key(TCAesKeySched_t s, const uint8_t *k); * schedule s * @note Assumes s was initialized by aes_set_encrypt_key; * out and in point to 16 byte buffers - * @return returns TC_SUCCESS (1) - * returns TC_FAIL (0) if: out == NULL or in == NULL or s == NULL + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: out == NULL or in == NULL or s == NULL * @param out IN/OUT -- buffer to receive ciphertext block * @param in IN -- a plaintext block to encrypt * @param s IN -- initialized AES key schedule @@ -98,8 +98,8 @@ int32_t tc_aes_encrypt(uint8_t *out, /** * @brief Set the AES-128 decryption key * Uses key k to initialize s - * @return returns TC_SUCCESS (1) - * returns TC_FAIL (0) if: s == NULL or k == NULL + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: s == NULL or k == NULL * @note This is the implementation of the straightforward inverse cipher * using the cipher documented in FIPS-197 figure 12, not the * equivalent inverse cipher presented in Figure 15 @@ -114,8 +114,8 @@ int32_t tc_aes128_set_decrypt_key(TCAesKeySched_t s, const uint8_t *k); /** * @brief AES-128 Encryption procedure * Decrypts in buffer into out buffer under key schedule s - * @return returns TC_SUCCESS (1) - * returns TC_FAIL (0) if: out is NULL or in is NULL or s is NULL + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: out is NULL or in is NULL or s is NULL * @note Assumes s was initialized by aes_set_encrypt_key * out and in point to 16 byte buffers * @param out IN/OUT -- buffer to receive ciphertext block diff --git a/ext/lib/crypto/tinycrypt/include/tinycrypt/cbc_mode.h b/ext/lib/crypto/tinycrypt/include/tinycrypt/cbc_mode.h index 25d926995..74d291425 100644 --- a/ext/lib/crypto/tinycrypt/include/tinycrypt/cbc_mode.h +++ b/ext/lib/crypto/tinycrypt/include/tinycrypt/cbc_mode.h @@ -84,8 +84,8 @@ extern "C" { * @brief CBC encryption procedure * CBC encrypts inlen bytes of the in buffer into the out buffer * using the encryption key schedule provided, prepends iv to out - * @return returns TC_SUCCESS (1) - * returns TC_FAIL (0) if: + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: * out == NULL or * in == NULL or * ctr == NULL or @@ -115,8 +115,8 @@ int32_t tc_cbc_mode_encrypt(uint8_t *out, uint32_t outlen, const uint8_t *in, * @brief CBC decryption procedure * CBC decrypts inlen bytes of the in buffer into the out buffer * using the provided encryption key schedule - * @return returns TC_SUCCESS (1) - * returns TC_FAIL (0) if: + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: * out == NULL or * in == NULL or * sched == NULL or diff --git a/ext/lib/crypto/tinycrypt/include/tinycrypt/ccm_mode.h b/ext/lib/crypto/tinycrypt/include/tinycrypt/ccm_mode.h index d01818855..9fa5915f0 100644 --- a/ext/lib/crypto/tinycrypt/include/tinycrypt/ccm_mode.h +++ b/ext/lib/crypto/tinycrypt/include/tinycrypt/ccm_mode.h @@ -96,8 +96,8 @@ typedef struct tc_ccm_mode_struct { /** * @brief CCM configuration procedure - * @return returns TC_SUCCESS (1) - * returns TC_FAIL (0) if: + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: * c == NULL or * sched == NULL or * nonce == NULL or @@ -113,8 +113,8 @@ int32_t tc_ccm_config(TCCcmMode_t c, TCAesKeySched_t sched, uint8_t *nonce, /** * @brief CCM tag generation and encryption procedure - * @return returns TC_SUCCESS (1) - * returns TC_FAIL (0) if: + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: * out == NULL or * c == NULL or * ((plen > 0) and (payload == NULL)) or @@ -155,8 +155,8 @@ int32_t tc_ccm_generation_encryption(uint8_t *out, const uint8_t *associated_dat /** * @brief CCM decryption and tag verification procedure - * @return returns TC_SUCCESS (1) - * returns TC_FAIL (0) if: + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: * out == NULL or * c == NULL or * ((plen > 0) and (payload == NULL)) or diff --git a/ext/lib/crypto/tinycrypt/include/tinycrypt/cmac_mode.h b/ext/lib/crypto/tinycrypt/include/tinycrypt/cmac_mode.h index 80f8462f2..9d3f13051 100644 --- a/ext/lib/crypto/tinycrypt/include/tinycrypt/cmac_mode.h +++ b/ext/lib/crypto/tinycrypt/include/tinycrypt/cmac_mode.h @@ -130,8 +130,8 @@ typedef struct tc_cmac_struct { /** * @brief Configures the CMAC state to use the given AES key - * @return returns TC_SUCCESS (1) after having configured the CMAC state - * returns TC_FAIL (0) if: + * @return returns TC_CRYPTO_SUCCESS (1) after having configured the CMAC state + * returns TC_CRYPTO_FAIL (0) if: * s == NULL or * key == NULL * @@ -144,8 +144,8 @@ int32_t tc_cmac_setup(TCCmacState_t s, const uint8_t *key, /** * @brief Erases the CMAC state - * @return returns TC_SUCCESS (1) after having configured the CMAC state - * returns TC_FAIL (0) if: + * @return returns TC_CRYPTO_SUCCESS (1) after having configured the CMAC state + * returns TC_CRYPTO_FAIL (0) if: * s == NULL * * @param s IN/OUT -- the state to erase @@ -154,8 +154,8 @@ int32_t tc_cmac_erase(TCCmacState_t s); /** * @brief Initializes a new CMAC computation - * @return returns TC_SUCCESS (1) after having initialized the CMAC state - * returns TC_FAIL (0) if: + * @return returns TC_CRYPTO_SUCCESS (1) after having initialized the CMAC state + * returns TC_CRYPTO_FAIL (0) if: * s == NULL * * @param s IN/OUT -- the state to initialize @@ -164,8 +164,8 @@ int32_t tc_cmac_init(TCCmacState_t s); /** * @brief Incrementally computes CMAC over the next data segment - * @return returns TC_SUCCESS (1) after successfully updating the CMAC state - * returns TC_FAIL (0) if: + * @return returns TC_CRYPTO_SUCCESS (1) after successfully updating the CMAC state + * returns TC_CRYPTO_FAIL (0) if: * s == NULL or * if data == NULL when dlen > 0 * @@ -177,8 +177,8 @@ int32_t tc_cmac_update(TCCmacState_t s, const uint8_t *data, size_t dlen); /** * @brief Generates the tag from the CMAC state - * @return returns TC_SUCCESS (1) after successfully generating the tag - * returns TC_FAIL (0) if: + * @return returns TC_CRYPTO_SUCCESS (1) after successfully generating the tag + * returns TC_CRYPTO_FAIL (0) if: * tag == NULL or * s == NULL * diff --git a/ext/lib/crypto/tinycrypt/include/tinycrypt/ctr_mode.h b/ext/lib/crypto/tinycrypt/include/tinycrypt/ctr_mode.h index b587a4446..5f7766ddc 100644 --- a/ext/lib/crypto/tinycrypt/include/tinycrypt/ctr_mode.h +++ b/ext/lib/crypto/tinycrypt/include/tinycrypt/ctr_mode.h @@ -77,8 +77,8 @@ extern "C" { /** * @brief CTR mode encryption/decryption procedure. * CTR mode encrypts (or decrypts) inlen bytes from in buffer into out buffer - * @return returns TC_SUCCESS (1) - * returns TC_FAIL (0) if: + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: * out == NULL or * in == NULL or * ctr == NULL or diff --git a/ext/lib/crypto/tinycrypt/include/tinycrypt/ctr_prng.h b/ext/lib/crypto/tinycrypt/include/tinycrypt/ctr_prng.h new file mode 100644 index 000000000..409d9ded3 --- /dev/null +++ b/ext/lib/crypto/tinycrypt/include/tinycrypt/ctr_prng.h @@ -0,0 +1,167 @@ +/* ctr_prng.h - TinyCrypt interface to a CTR-PRNG implementation */ + +/* + * Copyright (c) 2016, Chris Morrison + * 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. + * + * 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 HOLDER 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 a CTR-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 CTR-PRNG one + * which is based on AES. TinyCrypt implements CTR-PRNG with + * AES-128. + * + * 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 (AES-128 + * in this instance). + * + * Requires: - AES-128 + * + * Usage: 1) call tc_ctr_prng_init to seed the prng context + * + * 2) call tc_ctr_prng_reseed to mix in additional entropy into + * the prng context + * + * 3) call tc_ctr_prng_generate to output the pseudo-random data + * + * 4) call tc_ctr_prng_uninstantiate to zero out the prng context + */ + +#ifndef __TC_CTR_PRNG_H__ +#define __TC_CTR_PRNG_H__ + +#include <tinycrypt/aes.h> + +#define TC_CTR_PRNG_RESEED_REQ -1 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + /* updated each time another BLOCKLEN_BYTES bytes are produced */ + uint8_t V[TC_AES_BLOCK_SIZE]; + + /* updated whenever the PRNG is reseeded */ + struct tc_aes_key_sched_struct key; + + /* number of requests since initialization/reseeding */ + uint64_t reseedCount; +} TCCtrPrng_t; + + +/** + * @brief CTR-PRNG initialization procedure + * Initializes prng context with entropy and personalization string (if any) + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: + * ctx == NULL, + * entropy == NULL, + * entropyLen < (TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE) + * @note Only the first (TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE) bytes of + * both the entropy and personalization inputs are used - + * supplying additional bytes has no effect. + * @param ctx IN/OUT -- the PRNG context to initialize + * @param entropy IN -- entropy used to seed the PRNG + * @param entropyLen IN -- entropy length in bytes + * @param personalization IN -- personalization string used to seed the PRNG + * (may be null) + * @param pLen IN -- personalization length in bytes + * + */ +int32_t tc_ctr_prng_init(TCCtrPrng_t * const ctx, + uint8_t const * const entropy, + uint32_t entropyLen, + uint8_t const * const personalization, + uint32_t pLen); + +/** + * @brief CTR-PRNG reseed procedure + * Mixes entropy and additional_input into the prng context + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: + * ctx == NULL, + * entropy == NULL, + * entropylen < (TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE) + * @note It is better to reseed an existing prng context rather than + * re-initialise, so that any existing entropy in the context is + * presereved. This offers some protection against undetected failures + * of the entropy source. + * @note Assumes tc_ctr_prng_init has been called for ctx + * @param ctx IN/OUT -- the PRNG state + * @param entropy IN -- entropy to mix into the prng + * @param entropyLen IN -- length of entropy in bytes + * @param additional_input IN -- additional input to the prng (may be null) + * @param additionallen IN -- additional input length in bytes + */ +int32_t tc_ctr_prng_reseed(TCCtrPrng_t * const ctx, + uint8_t const * const entropy, + uint32_t entropyLen, + uint8_t const * const additional_input, + uint32_t additionallen); + +/** + * @brief CTR-PRNG generate procedure + * Generates outlen pseudo-random bytes into out buffer, updates prng + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CTR_PRNG_RESEED_REQ (-1) if a reseed is needed + * returns TC_CRYPTO_FAIL (0) if: + * ctx == NULL, + * out == NULL, + * outlen >= 2^16 + * @note Assumes tc_ctr_prng_init has been called for ctx + * @param ctx IN/OUT -- the PRNG context + * @param additional_input IN -- additional input to the prng (may be null) + * @param additionallen IN -- additional input length in bytes + * @param out IN/OUT -- buffer to receive output + * @param outlen IN -- size of out buffer in bytes + */ +int32_t tc_ctr_prng_generate(TCCtrPrng_t * const ctx, + uint8_t const * const additional_input, + uint32_t additionallen, + uint8_t * const out, + uint32_t outlen); + +/** + * @brief CTR-PRNG uninstantiate procedure + * Zeroes the internal state of the supplied prng context + * @return none + * @param ctx IN/OUT -- the PRNG context + */ +void tc_ctr_prng_uninstantiate(TCCtrPrng_t * const ctx); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/lib/crypto/tinycrypt/include/tinycrypt/ecc.h b/ext/lib/crypto/tinycrypt/include/tinycrypt/ecc.h index 3ccccc235..71194758c 100644 --- a/ext/lib/crypto/tinycrypt/include/tinycrypt/ecc.h +++ b/ext/lib/crypto/tinycrypt/include/tinycrypt/ecc.h @@ -277,8 +277,8 @@ void EccPoint_mult(EccPointJacobi *p_result, EccPoint *p_point, /* * @brief Convert an integer in standard octet representation to native format. - * @return returns TC_SUCCESS (1) - * returns TC_FAIL (0) if: + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: * out == NULL or * c == NULL or * ((plen > 0) and (payload == NULL)) or @@ -296,8 +296,8 @@ void ecc_bytes2native(uint32_t p_native[NUM_ECC_DIGITS], /* * @brief Convert an integer in native format to standard octet representation. - * @return returns TC_SUCCESS (1) - * returns TC_FAIL (0) if: + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: * out == NULL or * c == NULL or * ((plen > 0) and (payload == NULL)) or diff --git a/ext/lib/crypto/tinycrypt/include/tinycrypt/ecc_dh.h b/ext/lib/crypto/tinycrypt/include/tinycrypt/ecc_dh.h index 9a7285177..e296ba95b 100644 --- a/ext/lib/crypto/tinycrypt/include/tinycrypt/ecc_dh.h +++ b/ext/lib/crypto/tinycrypt/include/tinycrypt/ecc_dh.h @@ -80,8 +80,8 @@ extern "C" { /** * @brief Create a public/private key pair. - * @return returns TC_SUCCESS (1) if the key pair was generated successfully - * returns TC_FAIL (0) if: + * @return returns TC_CRYPTO_SUCCESS (1) if the key pair was generated successfully + * returns TC_CRYPTO_FAIL (0) if: * the private key is 0 * @param p_publicKey OUT -- the point representing the public key. @@ -114,8 +114,8 @@ int32_t ecc_valid_public_key(EccPoint *p_publicKey); /** * @brief Compute a shared secret given your secret key and someone else's * public key. - * @return returns TC_SUCCESS (1) if the shared secret was computed successfully - * returns TC_FAIL (0) otherwise + * @return returns TC_CRYPTO_SUCCESS (1) if the shared secret was computed successfully + * returns TC_CRYPTO_FAIL (0) otherwise * * @param p_secret OUT -- The shared secret value. * @param p_publicKey IN -- The public key of the remote party. diff --git a/ext/lib/crypto/tinycrypt/include/tinycrypt/ecc_dsa.h b/ext/lib/crypto/tinycrypt/include/tinycrypt/ecc_dsa.h index 7aaf8d5f6..a037fa5b0 100644 --- a/ext/lib/crypto/tinycrypt/include/tinycrypt/ecc_dsa.h +++ b/ext/lib/crypto/tinycrypt/include/tinycrypt/ecc_dsa.h @@ -87,8 +87,8 @@ extern "C" { /** * @brief Generate an ECDSA signature for a given hash value. - * @return returns TC_SUCCESS (1) if the the signature generated successfully - * returns TC_FAIL (0) if: + * @return returns TC_CRYPTO_SUCCESS (1) if the the signature generated successfully + * returns TC_CRYPTO_FAIL (0) if: * r == 0 or * p_random == 0 * @@ -112,8 +112,8 @@ int32_t ecdsa_sign(uint32_t r[NUM_ECC_DIGITS], uint32_t s[NUM_ECC_DIGITS], /** * @brief Verify an ECDSA signature. - * @return returns TC_SUCCESS (1) if the the signature generated successfully - * returns TC_FAIL (0) if: + * @return returns TC_CRYPTO_SUCCESS (1) if the the signature generated successfully + * returns TC_CRYPTO_FAIL (0) if: * r == 0 or * p_random == 0 * diff --git a/ext/lib/crypto/tinycrypt/include/tinycrypt/hmac.h b/ext/lib/crypto/tinycrypt/include/tinycrypt/hmac.h index 99a1d8821..41e712a39 100644 --- a/ext/lib/crypto/tinycrypt/include/tinycrypt/hmac.h +++ b/ext/lib/crypto/tinycrypt/include/tinycrypt/hmac.h @@ -80,8 +80,8 @@ typedef struct tc_hmac_state_struct *TCHmacState_t; /** * @brief HMAC set key procedure * Configures ctx to use key - * @return returns TC_SUCCESS (1) - * returns TC_FAIL (0) if + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if * ctx == NULL or * key == NULL or * key_size == 0 @@ -96,8 +96,8 @@ int32_t tc_hmac_set_key(TCHmacState_t ctx, /** * @brief HMAC init procedure * Initializes ctx to begin the next HMAC operation - * @return returns TC_SUCCESS (1) - * returns TC_FAIL (0) if: ctx == NULL or key == NULL + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: ctx == NULL or key == NULL * @param ctx IN/OUT -- struct tc_hmac_state_struct buffer to init */ int32_t tc_hmac_init(TCHmacState_t ctx); @@ -105,8 +105,8 @@ int32_t tc_hmac_init(TCHmacState_t ctx); /** * @brief HMAC update procedure * Mixes data_length bytes addressed by data into state - * @return returns TC_SUCCCESS (1) - * returns TC_FAIL (0) if: ctx == NULL or key == NULL + * @return returns TC_CRYPTO_SUCCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: ctx == NULL or key == NULL * @note Assumes state has been initialized by tc_hmac_init * @param ctx IN/OUT -- state of HMAC computation so far * @param data IN -- data to incorporate into state @@ -119,8 +119,8 @@ int32_t tc_hmac_update(TCHmacState_t ctx, /** * @brief HMAC final procedure * Writes the HMAC tag into the tag buffer - * @return returns TC_SUCCESS (1) - * returns TC_FAIL (0) if: + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: * tag == NULL or * ctx == NULL or * key == NULL or diff --git a/ext/lib/crypto/tinycrypt/include/tinycrypt/hmac_prng.h b/ext/lib/crypto/tinycrypt/include/tinycrypt/hmac_prng.h index 54785f878..b631c2c87 100644 --- a/ext/lib/crypto/tinycrypt/include/tinycrypt/hmac_prng.h +++ b/ext/lib/crypto/tinycrypt/include/tinycrypt/hmac_prng.h @@ -93,8 +93,8 @@ 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_SUCCESS (1) - * returns TC_FAIL (0) if: + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: * prng == NULL, * personalization == NULL, * plen > MAX_PLEN @@ -119,8 +119,8 @@ int32_t tc_hmac_prng_init(TCHmacPrng_t prng, /** * @brief HMAC-PRNG reseed procedure * Mixes seed into prng, enables tc_hmac_prng_generate - * @return returns TC_SUCCESS (1) - * returns TC_FAIL (0) if: + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: * prng == NULL, * seed == NULL, * seedlen < MIN_SLEN, @@ -143,9 +143,9 @@ int32_t tc_hmac_prng_reseed(TCHmacPrng_t prng, const uint8_t *seed, /** * @brief HMAC-PRNG generate procedure * Generates outlen pseudo-random bytes into out buffer, updates prng - * @return returns TC_SUCCESS (1) + * @return returns TC_CRYPTO_SUCCESS (1) * returns TC_HMAC_PRNG_RESEED_REQ (-1) if a reseed is needed - * returns TC_FAIL (0) if: + * returns TC_CRYPTO_FAIL (0) if: * out == NULL, * prng == NULL, * outlen == 0, diff --git a/ext/lib/crypto/tinycrypt/include/tinycrypt/sha256.h b/ext/lib/crypto/tinycrypt/include/tinycrypt/sha256.h index c8c9c57af..e7c3ba0d3 100644 --- a/ext/lib/crypto/tinycrypt/include/tinycrypt/sha256.h +++ b/ext/lib/crypto/tinycrypt/include/tinycrypt/sha256.h @@ -80,8 +80,8 @@ typedef struct tc_sha256_state_struct *TCSha256State_t; /** * @brief SHA256 initialization procedure * Initializes s - * @return returns TC_SUCCESS (1) - * returns TC_FAIL (0) if s == NULL + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if s == NULL * @param s Sha256 state struct */ int32_t tc_sha256_init(TCSha256State_t s); @@ -89,8 +89,8 @@ int32_t tc_sha256_init(TCSha256State_t s); /** * @brief SHA256 update procedure * Hashes data_length bytes addressed by data into state s - * @return returns TC_SUCCESS (1) - * returns TC_FAIl (0) if: + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: * s == NULL, * s->iv == NULL, * data == NULL @@ -109,8 +109,8 @@ int32_t tc_sha256_update(TCSha256State_t s, /** * @brief SHA256 final procedure * Inserts the completed hash computation into digest - * @return returns TC_SUCCESS (1) - * returns TC_FAIL (0) if: + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: * s == NULL, * s->iv == NULL, * digest == NULL @@ -120,7 +120,7 @@ int32_t tc_sha256_update(TCSha256State_t s, * If your application intends to have sensitive data in this * buffer, remind to erase it after the data has been processed * @param digest unsigned eight bit integer - * @param s Sha256 state struct + * @param s state struct */ int32_t tc_sha256_final(uint8_t *digest, TCSha256State_t s); diff --git a/ext/lib/crypto/tinycrypt/include/tinycrypt/utils.h b/ext/lib/crypto/tinycrypt/include/tinycrypt/utils.h index 27ddc6f10..429934e8f 100644 --- a/ext/lib/crypto/tinycrypt/include/tinycrypt/utils.h +++ b/ext/lib/crypto/tinycrypt/include/tinycrypt/utils.h @@ -46,14 +46,10 @@ extern "C" { #endif -#define TC_SUCCESS 1 -#define TC_FAIL 0 -#define TC_RESEED_REQ -1 - /** * @brief Copy the the buffer 'from' to the buffer 'to'. - * @return returns TC_SUCCESS (1) - * returns TC_FAIL (0) if: + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: * from_len > to_len. * * @param to OUT -- destination buffer diff --git a/ext/lib/crypto/tinycrypt/source/aes_decrypt.c b/ext/lib/crypto/tinycrypt/source/aes_decrypt.c index 9291d4e21..2e4e3bceb 100644 --- a/ext/lib/crypto/tinycrypt/source/aes_decrypt.c +++ b/ext/lib/crypto/tinycrypt/source/aes_decrypt.c @@ -134,11 +134,11 @@ int32_t tc_aes_decrypt(uint8_t *out, const uint8_t *in, const TCAesKeySched_t s) uint32_t i; if (out == (uint8_t *) 0) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } else if (in == (const uint8_t *) 0) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } else if (s == (TCAesKeySched_t) 0) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } (void)_copy(state, sizeof(state), in, sizeof(state)); @@ -160,5 +160,5 @@ int32_t tc_aes_decrypt(uint8_t *out, const uint8_t *in, const TCAesKeySched_t s) /*zeroing out one byte state buffer */ _set(state, ZERO_BYTE, sizeof(state)); - return TC_SUCCESS; + return TC_CRYPTO_SUCCESS; } diff --git a/ext/lib/crypto/tinycrypt/source/aes_encrypt.c b/ext/lib/crypto/tinycrypt/source/aes_encrypt.c index 898af0aa0..6bc73a581 100644 --- a/ext/lib/crypto/tinycrypt/source/aes_encrypt.c +++ b/ext/lib/crypto/tinycrypt/source/aes_encrypt.c @@ -77,9 +77,9 @@ int32_t tc_aes128_set_encrypt_key(TCAesKeySched_t s, const uint8_t *k) uint32_t t; if (s == (TCAesKeySched_t) 0) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } else if (k == (const uint8_t *) 0) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } for (i = 0; i < Nk; ++i) { @@ -95,7 +95,7 @@ int32_t tc_aes128_set_encrypt_key(TCAesKeySched_t s, const uint8_t *k) s->words[i] = s->words[i-Nk] ^ t; } - return TC_SUCCESS; + return TC_CRYPTO_SUCCESS; } static inline void add_round_key(uint8_t *s, const uint32_t *k) @@ -161,11 +161,11 @@ int32_t tc_aes_encrypt(uint8_t *out, const uint8_t *in, const TCAesKeySched_t s) uint32_t i; if (out == (uint8_t *) 0) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } else if (in == (const uint8_t *) 0) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } else if (s == (TCAesKeySched_t) 0) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } (void)_copy(state, sizeof(state), in, sizeof(state)); @@ -187,5 +187,5 @@ int32_t tc_aes_encrypt(uint8_t *out, const uint8_t *in, const TCAesKeySched_t s) /* zeroing out the state buffer */ _set(state, TC_ZERO_BYTE, sizeof(state)); - return TC_SUCCESS; + return TC_CRYPTO_SUCCESS; } diff --git a/ext/lib/crypto/tinycrypt/source/cbc_mode.c b/ext/lib/crypto/tinycrypt/source/cbc_mode.c index 759360b31..8163e0d38 100644 --- a/ext/lib/crypto/tinycrypt/source/cbc_mode.c +++ b/ext/lib/crypto/tinycrypt/source/cbc_mode.c @@ -51,7 +51,7 @@ int32_t tc_cbc_mode_encrypt(uint8_t *out, uint32_t outlen, const uint8_t *in, (inlen % TC_AES_BLOCK_SIZE) != 0 || (outlen % TC_AES_BLOCK_SIZE) != 0 || outlen != inlen + TC_AES_BLOCK_SIZE) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } /* copy iv to the buffer */ @@ -71,7 +71,7 @@ int32_t tc_cbc_mode_encrypt(uint8_t *out, uint32_t outlen, const uint8_t *in, } } - return TC_SUCCESS; + return TC_CRYPTO_SUCCESS; } int32_t tc_cbc_mode_decrypt(uint8_t *out, uint32_t outlen, const uint8_t *in, @@ -91,7 +91,7 @@ int32_t tc_cbc_mode_decrypt(uint8_t *out, uint32_t outlen, const uint8_t *in, (inlen % TC_AES_BLOCK_SIZE) != 0 || (outlen % TC_AES_BLOCK_SIZE) != 0 || outlen != inlen - TC_AES_BLOCK_SIZE) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } /* @@ -109,5 +109,5 @@ int32_t tc_cbc_mode_decrypt(uint8_t *out, uint32_t outlen, const uint8_t *in, *out++ = buffer[m++] ^ *p++; } - return TC_SUCCESS; + return TC_CRYPTO_SUCCESS; } diff --git a/ext/lib/crypto/tinycrypt/source/ccm_mode.c b/ext/lib/crypto/tinycrypt/source/ccm_mode.c index ff01f2175..3e3b90c2b 100644 --- a/ext/lib/crypto/tinycrypt/source/ccm_mode.c +++ b/ext/lib/crypto/tinycrypt/source/ccm_mode.c @@ -44,18 +44,18 @@ int32_t tc_ccm_config(TCCcmMode_t c, TCAesKeySched_t sched, uint8_t *nonce, if (c == (TCCcmMode_t) 0 || sched == (TCAesKeySched_t) 0 || nonce == (uint8_t *) 0) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } else if (nlen != 13) { - return TC_FAIL; /* The allowed nonce size is: 13. See documentation.*/ + return TC_CRYPTO_FAIL; /* The allowed nonce size is: 13. See documentation.*/ } else if ((mlen < 4) || (mlen > 16) || (mlen & 1)) { - return TC_FAIL; /* The allowed mac sizes are: 4, 6, 8, 10, 12, 14, 16.*/ + return TC_CRYPTO_FAIL; /* The allowed mac sizes are: 4, 6, 8, 10, 12, 14, 16.*/ } c->mlen = mlen; c->sched = sched; c->nonce = nonce; - return TC_SUCCESS; + return TC_CRYPTO_SUCCESS; } /** @@ -107,7 +107,7 @@ static int32_t ccm_ctr_mode(uint8_t *out, uint32_t outlen, const uint8_t *in, inlen == 0 || outlen == 0 || outlen != inlen) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } /* copy the counter to the nonce */ @@ -121,7 +121,7 @@ static int32_t ccm_ctr_mode(uint8_t *out, uint32_t outlen, const uint8_t *in, nonce[14] = (uint8_t)(block_num >> 8); nonce[15] = (uint8_t)(block_num); if (!tc_aes_encrypt(buffer, nonce, sched)) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } } /* update the output */ @@ -131,7 +131,7 @@ static int32_t ccm_ctr_mode(uint8_t *out, uint32_t outlen, const uint8_t *in, /* update the counter */ ctr[14] = nonce[14]; ctr[15] = nonce[15]; - return TC_SUCCESS; + return TC_CRYPTO_SUCCESS; } int32_t tc_ccm_generation_encryption(uint8_t *out, const uint8_t *associated_data, @@ -145,7 +145,7 @@ int32_t tc_ccm_generation_encryption(uint8_t *out, const uint8_t *associated_dat ((alen > 0) && (associated_data == (uint8_t *) 0)) || (alen >= TC_CCM_AAD_MAX_BYTES) || /* associated data size unsupported */ (plen >= TC_CCM_PAYLOAD_MAX_BYTES)) { /* payload size unsupported */ - return TC_FAIL; + return TC_CRYPTO_FAIL; } uint8_t b[Nb * Nk]; @@ -189,7 +189,7 @@ int32_t tc_ccm_generation_encryption(uint8_t *out, const uint8_t *associated_dat *out++ = tag[i] ^ b[i]; } - return TC_SUCCESS; + return TC_CRYPTO_SUCCESS; } int32_t tc_ccm_decryption_verification(uint8_t *out, const uint8_t *associated_data, @@ -205,7 +205,7 @@ int32_t tc_ccm_decryption_verification(uint8_t *out, const uint8_t *associated_d ((alen > 0) && (associated_data == (uint8_t *) 0)) || (alen >= TC_CCM_AAD_MAX_BYTES) || /* associated data size unsupported */ (plen >= TC_CCM_PAYLOAD_MAX_BYTES)) { /* payload size unsupported */ - return TC_FAIL; + return TC_CRYPTO_FAIL; } uint8_t b[Nb * Nk]; @@ -255,8 +255,8 @@ int32_t tc_ccm_decryption_verification(uint8_t *out, const uint8_t *associated_d if (_compare(b, tag, c->mlen) != 0) { /* erase the decrypted buffer in case of mac validation failure: */ _set(out, 0, sizeof(*out)); - return TC_FAIL; + return TC_CRYPTO_FAIL; } - return TC_SUCCESS; + return TC_CRYPTO_SUCCESS; } diff --git a/ext/lib/crypto/tinycrypt/source/cmac_mode.c b/ext/lib/crypto/tinycrypt/source/cmac_mode.c index 99cdf7b4b..3b31c3e6f 100644 --- a/ext/lib/crypto/tinycrypt/source/cmac_mode.c +++ b/ext/lib/crypto/tinycrypt/source/cmac_mode.c @@ -100,7 +100,7 @@ int32_t tc_cmac_setup(TCCmacState_t s, const uint8_t *key, TCAesKeySched_t sched /* input sanity check: */ if (s == (TCCmacState_t) 0 || key == (const uint8_t *) 0) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } /* put s into a known state */ @@ -119,26 +119,26 @@ int32_t tc_cmac_setup(TCCmacState_t s, const uint8_t *key, TCAesKeySched_t sched /* reset s->iv to 0 in case someone wants to compute now */ tc_cmac_init(s); - return TC_SUCCESS; + return TC_CRYPTO_SUCCESS; } int32_t tc_cmac_erase(TCCmacState_t s) { if (s == (TCCmacState_t) 0) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } /* destroy the current state */ _set(s, 0, sizeof(*s)); - return TC_SUCCESS; + return TC_CRYPTO_SUCCESS; } int32_t tc_cmac_init(TCCmacState_t s) { /* input sanity check: */ if (s == (TCCmacState_t) 0) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } /* CMAC starts with an all zero initialization vector */ @@ -151,7 +151,7 @@ int32_t tc_cmac_init(TCCmacState_t s) /* Set countdown to max number of calls allowed before re-keying: */ s->countdown = MAX_CALLS; - return TC_SUCCESS; + return TC_CRYPTO_SUCCESS; } int32_t tc_cmac_update(TCCmacState_t s, const uint8_t *data, size_t data_length) @@ -160,17 +160,17 @@ int32_t tc_cmac_update(TCCmacState_t s, const uint8_t *data, size_t data_length) /* input sanity check: */ if (s == (TCCmacState_t) 0) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } if (data_length == 0) { - return TC_SUCCESS; + return TC_CRYPTO_SUCCESS; } if (data == (const uint8_t *) 0) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } if (s->countdown == 0) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } s->countdown--; @@ -183,7 +183,7 @@ int32_t tc_cmac_update(TCCmacState_t s, const uint8_t *data, size_t data_length) /* still not enough data to encrypt this time either */ _copy(&s->leftover[s->leftover_offset], data_length, data, data_length); s->leftover_offset += data_length; - return TC_SUCCESS; + return TC_CRYPTO_SUCCESS; } /* leftover block is now full; encrypt it first */ _copy(&s->leftover[s->leftover_offset], @@ -216,7 +216,7 @@ int32_t tc_cmac_update(TCCmacState_t s, const uint8_t *data, size_t data_length) s->leftover_offset = data_length; } - return TC_SUCCESS; + return TC_CRYPTO_SUCCESS; } int32_t tc_cmac_final(uint8_t *tag, TCCmacState_t s) @@ -227,7 +227,7 @@ int32_t tc_cmac_final(uint8_t *tag, TCCmacState_t s) /* input sanity check: */ if (tag == (uint8_t *) 0 || s == (TCCmacState_t) 0) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } if (s->leftover_offset == TC_AES_BLOCK_SIZE) { @@ -250,5 +250,5 @@ int32_t tc_cmac_final(uint8_t *tag, TCCmacState_t s) /* erasing state: */ tc_cmac_erase(s); - return TC_SUCCESS; + return TC_CRYPTO_SUCCESS; } diff --git a/ext/lib/crypto/tinycrypt/source/ctr_mode.c b/ext/lib/crypto/tinycrypt/source/ctr_mode.c index cb0a08b74..7ba53d024 100644 --- a/ext/lib/crypto/tinycrypt/source/ctr_mode.c +++ b/ext/lib/crypto/tinycrypt/source/ctr_mode.c @@ -51,7 +51,7 @@ int32_t tc_ctr_mode(uint8_t *out, uint32_t outlen, const uint8_t *in, inlen == 0 || outlen == 0 || outlen != inlen) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } /* copy the ctr to the nonce */ @@ -70,7 +70,7 @@ int32_t tc_ctr_mode(uint8_t *out, uint32_t outlen, const uint8_t *in, nonce[14] = (uint8_t)(block_num >> 8); nonce[15] = (uint8_t)(block_num); } else { - return TC_FAIL; + return TC_CRYPTO_FAIL; } } /* update the output */ @@ -81,5 +81,5 @@ int32_t tc_ctr_mode(uint8_t *out, uint32_t outlen, const uint8_t *in, ctr[12] = nonce[12]; ctr[13] = nonce[13]; ctr[14] = nonce[14]; ctr[15] = nonce[15]; - return TC_SUCCESS; + return TC_CRYPTO_SUCCESS; } diff --git a/ext/lib/crypto/tinycrypt/source/ctr_prng.c b/ext/lib/crypto/tinycrypt/source/ctr_prng.c new file mode 100644 index 000000000..92fc62970 --- /dev/null +++ b/ext/lib/crypto/tinycrypt/source/ctr_prng.c @@ -0,0 +1,308 @@ +/* ctr_prng.c - TinyCrypt implementation of CTR-PRNG */ + +/* + * Copyright (c) 2016, Chris Morrison + * 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. + * + * 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 HOLDER 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. + */ + +#include <tinycrypt/ctr_prng.h> +#include <tinycrypt/utils.h> +#include <tinycrypt/constants.h> +#include <string.h> + +/* + * This PRNG is based on the CTR_DRBG described in Recommendation for Random + * Number Generation Using Deterministic Random Bit Generators, + * NIST SP 800-90A Rev. 1. + * + * Annotations to particular steps (e.g. 10.2.1.2 Step 1) refer to the steps + * described in that document. + * + */ + +/** + * @brief Array incrementer + * Treats the supplied array as one contiguous number (MSB in arr[0]), and + * increments it by one + * @return none + * @param arr IN/OUT -- array to be incremented + * @param len IN -- size of arr in bytes + */ +static void arrInc(uint8_t arr[], uint32_t len) +{ + uint32_t i; + if (0 != arr) + { + for (i = len; i > 0U; i--) + { + if (++arr[i-1] != 0U) + { + break; + } + } + } +} + +/** + * @brief CTR PRNG update + * Updates the internal state of supplied the CTR PRNG context + * increments it by one + * @return none + * @note Assumes: providedData is (TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE) bytes long + * @param ctx IN/OUT -- CTR PRNG state + * @param providedData IN -- data used when updating the internal state + */ +static void tc_ctr_prng_update(TCCtrPrng_t * const ctx, uint8_t const * const providedData) +{ + if (0 != ctx) + { + /* 10.2.1.2 step 1 */ + uint8_t temp[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE]; + uint32_t len = 0U; + + /* 10.2.1.2 step 2 */ + while (len < sizeof temp) + { + uint32_t blocklen = sizeof(temp) - len; + uint8_t output_block[TC_AES_BLOCK_SIZE]; + + /* 10.2.1.2 step 2.1 */ + arrInc(ctx->V, sizeof ctx->V); + + /* 10.2.1.2 step 2.2 */ + if (blocklen > TC_AES_BLOCK_SIZE) + { + blocklen = TC_AES_BLOCK_SIZE; + } + (void)tc_aes_encrypt(output_block, ctx->V, &ctx->key); + + /* 10.2.1.2 step 2.3/step 3 */ + memcpy(&(temp[len]), output_block, blocklen); + + len += blocklen; + } + + /* 10.2.1.2 step 4 */ + if (0 != providedData) + { + uint32_t i; + for (i = 0U; i < sizeof temp; i++) + { + temp[i] ^= providedData[i]; + } + } + + /* 10.2.1.2 step 5 */ + (void)tc_aes128_set_encrypt_key(&ctx->key, temp); + + /* 10.2.1.2 step 6 */ + memcpy(ctx->V, &(temp[TC_AES_KEY_SIZE]), TC_AES_BLOCK_SIZE); + } +} + +int32_t tc_ctr_prng_init(TCCtrPrng_t * const ctx, + uint8_t const * const entropy, + uint32_t entropyLen, + uint8_t const * const personalization, + uint32_t pLen) +{ + int32_t result = TC_CRYPTO_FAIL; + uint32_t i; + uint8_t personalization_buf[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE] = {0U}; + uint8_t seed_material[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE]; + uint8_t zeroArr[TC_AES_BLOCK_SIZE] = {0U}; + + if (0 != personalization) + { + /* 10.2.1.3.1 step 1 */ + uint32_t len = pLen; + if (len > sizeof personalization_buf) + { + len = sizeof personalization_buf; + } + + /* 10.2.1.3.1 step 2 */ + memcpy(personalization_buf, personalization, len); + } + + if ((0 != ctx) && (0 != entropy) && (entropyLen >= sizeof seed_material)) + { + /* 10.2.1.3.1 step 3 */ + memcpy(seed_material, entropy, sizeof seed_material); + for (i = 0U; i < sizeof seed_material; i++) + { + seed_material[i] ^= personalization_buf[i]; + } + + /* 10.2.1.3.1 step 4 */ + (void)tc_aes128_set_encrypt_key(&ctx->key, zeroArr); + + /* 10.2.1.3.1 step 5 */ + memset(ctx->V, 0x00, sizeof ctx->V); + + /* 10.2.1.3.1 step 6 */ + tc_ctr_prng_update(ctx, seed_material); + + /* 10.2.1.3.1 step 7 */ + ctx->reseedCount = 1U; + + result = TC_CRYPTO_SUCCESS; + } + return result; +} + +int32_t tc_ctr_prng_reseed(TCCtrPrng_t * const ctx, + uint8_t const * const entropy, + uint32_t entropyLen, + uint8_t const * const additional_input, + uint32_t additionallen) +{ + uint32_t i; + int32_t result = TC_CRYPTO_FAIL; + uint8_t additional_input_buf[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE] = {0U}; + uint8_t seed_material[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE]; + + if (0 != additional_input) + { + /* 10.2.1.4.1 step 1 */ + uint32_t len = additionallen; + if (len > sizeof additional_input_buf) + { + len = sizeof additional_input_buf; + } + + /* 10.2.1.4.1 step 2 */ + memcpy(additional_input_buf, additional_input, len); + } + + uint32_t seedlen = (uint32_t)TC_AES_KEY_SIZE + (uint32_t)TC_AES_BLOCK_SIZE; + if ((0 != ctx) && (entropyLen >= seedlen)) + { + /* 10.2.1.4.1 step 3 */ + memcpy(seed_material, entropy, sizeof seed_material); + for (i = 0U; i < sizeof seed_material; i++) + { + seed_material[i] ^= additional_input_buf[i]; + } + + /* 10.2.1.4.1 step 4 */ + tc_ctr_prng_update(ctx, entropy); + + /* 10.2.1.4.1 step 5 */ + ctx->reseedCount = 1U; + + result = TC_CRYPTO_SUCCESS; + } + return result; +} + +int32_t tc_ctr_prng_generate(TCCtrPrng_t * const ctx, + uint8_t const * const additional_input, + uint32_t additionallen, + uint8_t * const out, + uint32_t outlen) +{ + /* 2^48 - see section 10.2.1 */ + static const uint64_t MAX_REQS_BEFORE_RESEED = 0x1000000000000ULL; + + /* 2^19 bits - see section 10.2.1 */ + static const uint32_t MAX_BYTES_PER_REQ = 65536U; + + int32_t result = TC_CRYPTO_FAIL; + + if ((0 != ctx) && (0 != out) && (outlen < MAX_BYTES_PER_REQ)) + { + /* 10.2.1.5.1 step 1 */ + if (ctx->reseedCount > MAX_REQS_BEFORE_RESEED) + { + result = TC_CTR_PRNG_RESEED_REQ; + } + else + { + uint8_t additional_input_buf[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE] = {0U}; + if (0 != additional_input) + { + /* 10.2.1.5.1 step 2 */ + uint32_t len = additionallen; + if (len > sizeof additional_input_buf) + { + len = sizeof additional_input_buf; + } + memcpy(additional_input_buf, additional_input, len); + tc_ctr_prng_update(ctx, additional_input_buf); + } + + /* 10.2.1.5.1 step 3 - implicit */ + + /* 10.2.1.5.1 step 4 */ + uint32_t len = 0U; + while (len < outlen) + { + uint32_t blocklen = outlen - len; + uint8_t output_block[TC_AES_BLOCK_SIZE]; + + /* 10.2.1.5.1 step 4.1 */ + arrInc(ctx->V, sizeof ctx->V); + + /* 10.2.1.5.1 step 4.2 */ + (void)tc_aes_encrypt(output_block, ctx->V, &ctx->key); + + /* 10.2.1.5.1 step 4.3/step 5 */ + if (blocklen > TC_AES_BLOCK_SIZE) + { + blocklen = TC_AES_BLOCK_SIZE; + } + memcpy(&(out[len]), output_block, blocklen); + + len += blocklen; + } + + /* 10.2.1.5.1 step 6 */ + tc_ctr_prng_update(ctx, additional_input_buf); + + /* 10.2.1.5.1 step 7 */ + ctx->reseedCount++; + + /* 10.2.1.5.1 step 8 */ + result = TC_CRYPTO_SUCCESS; + } + } + + return result; +} + +void tc_ctr_prng_uninstantiate(TCCtrPrng_t * const ctx) +{ + if (0 != ctx) + { + memset(ctx->key.words, 0x00, sizeof ctx->key.words); + memset(ctx->V, 0x00, sizeof ctx->V); + ctx->reseedCount = 0U; + } +} + + + + diff --git a/ext/lib/crypto/tinycrypt/source/hmac.c b/ext/lib/crypto/tinycrypt/source/hmac.c index b9af4a626..442af547a 100644 --- a/ext/lib/crypto/tinycrypt/source/hmac.c +++ b/ext/lib/crypto/tinycrypt/source/hmac.c @@ -57,7 +57,7 @@ int32_t tc_hmac_set_key(TCHmacState_t ctx, if (ctx == (TCHmacState_t) 0 || key == (const uint8_t *) 0 || key_size == 0) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } const uint8_t dummy_key[key_size]; @@ -90,7 +90,7 @@ int32_t tc_hmac_set_key(TCHmacState_t ctx, TC_SHA256_DIGEST_SIZE); } - return TC_SUCCESS; + return TC_CRYPTO_SUCCESS; } int32_t tc_hmac_init(TCHmacState_t ctx) @@ -98,7 +98,7 @@ int32_t tc_hmac_init(TCHmacState_t ctx) /* input sanity check: */ if (ctx == (TCHmacState_t) 0 || ctx->key == (uint8_t *) 0) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } (void)tc_sha256_init(&ctx->hash_state); @@ -106,7 +106,7 @@ int32_t tc_hmac_init(TCHmacState_t ctx) ctx->key, TC_SHA256_BLOCK_SIZE); - return TC_SUCCESS; + return TC_CRYPTO_SUCCESS; } int32_t tc_hmac_update(TCHmacState_t ctx, @@ -115,12 +115,12 @@ int32_t tc_hmac_update(TCHmacState_t ctx, { /* input sanity check: */ if (ctx == (TCHmacState_t) 0 || ctx->key == (uint8_t *) 0) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } (void)tc_sha256_update(&ctx->hash_state, data, data_length); - return TC_SUCCESS; + return TC_CRYPTO_SUCCESS; } int32_t tc_hmac_final(uint8_t *tag, uint32_t taglen, TCHmacState_t ctx) @@ -130,7 +130,7 @@ int32_t tc_hmac_final(uint8_t *tag, uint32_t taglen, TCHmacState_t ctx) taglen != TC_SHA256_DIGEST_SIZE || ctx == (TCHmacState_t) 0 || ctx->key == (uint8_t *) 0) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } (void) tc_sha256_final(tag, &ctx->hash_state); @@ -145,5 +145,5 @@ int32_t tc_hmac_final(uint8_t *tag, uint32_t taglen, TCHmacState_t ctx) /* destroy the current state */ _set(ctx, 0, sizeof(*ctx)); - return TC_SUCCESS; + return TC_CRYPTO_SUCCESS; } diff --git a/ext/lib/crypto/tinycrypt/source/hmac_prng.c b/ext/lib/crypto/tinycrypt/source/hmac_prng.c index c24c37e7a..ceac27f69 100644 --- a/ext/lib/crypto/tinycrypt/source/hmac_prng.c +++ b/ext/lib/crypto/tinycrypt/source/hmac_prng.c @@ -1,4 +1,4 @@ -/* Hmac_prng.c - TinyCrypt implementation of HMAC-PRNG */ +/* hmac_prng.c - TinyCrypt implementation of HMAC-PRNG */ /* * Copyright (C) 2015 by Intel Corporation, All Rights Reserved. @@ -117,7 +117,7 @@ int32_t tc_hmac_prng_init(TCHmacPrng_t prng, if (prng == (TCHmacPrng_t) 0 || personalization == (uint8_t *) 0 || plen > MAX_PLEN) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } /* put the generator into a known state: */ @@ -131,7 +131,7 @@ int32_t tc_hmac_prng_init(TCHmacPrng_t prng, /* force a reseed before allowing tc_hmac_prng_generate to succeed: */ prng->countdown = 0; - return TC_SUCCESS; + return TC_CRYPTO_SUCCESS; } int32_t tc_hmac_prng_reseed(TCHmacPrng_t prng, @@ -145,7 +145,7 @@ int32_t tc_hmac_prng_reseed(TCHmacPrng_t prng, seed == (const uint8_t *) 0 || seedlen < MIN_SLEN || seedlen > MAX_SLEN) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } if (additional_input != (const uint8_t *) 0) { @@ -155,7 +155,7 @@ int32_t tc_hmac_prng_reseed(TCHmacPrng_t prng, */ if (additionallen == 0 || additionallen > MAX_ALEN) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } else { /* call update for the seed and additional_input */ update(prng, seed, seedlen); @@ -169,7 +169,7 @@ int32_t tc_hmac_prng_reseed(TCHmacPrng_t prng, /* ... and enable hmac_prng_generate */ prng->countdown = MAX_GENS; - return TC_SUCCESS; + return TC_CRYPTO_SUCCESS; } int32_t tc_hmac_prng_generate(uint8_t *out, uint32_t outlen, TCHmacPrng_t prng) @@ -181,7 +181,7 @@ int32_t tc_hmac_prng_generate(uint8_t *out, uint32_t outlen, TCHmacPrng_t prng) prng == (TCHmacPrng_t) 0 || outlen == 0 || outlen > MAX_OUT) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } else if (prng->countdown == 0) { return TC_HMAC_PRNG_RESEED_REQ; } @@ -206,5 +206,5 @@ int32_t tc_hmac_prng_generate(uint8_t *out, uint32_t outlen, TCHmacPrng_t prng) /* block future PRNG compromises from revealing past state */ update(prng, prng->v, TC_SHA256_DIGEST_SIZE); - return TC_SUCCESS; + return TC_CRYPTO_SUCCESS; } diff --git a/ext/lib/crypto/tinycrypt/source/sha256.c b/ext/lib/crypto/tinycrypt/source/sha256.c index 1dced7627..a02e46477 100644 --- a/ext/lib/crypto/tinycrypt/source/sha256.c +++ b/ext/lib/crypto/tinycrypt/source/sha256.c @@ -40,7 +40,7 @@ int32_t tc_sha256_init(TCSha256State_t s) { /* input sanity check: */ if (s == (TCSha256State_t) 0) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } /* @@ -59,7 +59,7 @@ int32_t tc_sha256_init(TCSha256State_t s) s->iv[6] = 0x1f83d9ab; s->iv[7] = 0x5be0cd19; - return TC_SUCCESS; + return TC_CRYPTO_SUCCESS; } int32_t tc_sha256_update(TCSha256State_t s, const uint8_t *data, size_t datalen) @@ -68,9 +68,9 @@ int32_t tc_sha256_update(TCSha256State_t s, const uint8_t *data, size_t datalen) if (s == (TCSha256State_t) 0 || s->iv == (uint32_t *) 0 || data == (void *) 0) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } else if (datalen == 0) { - return TC_SUCCESS; + return TC_CRYPTO_SUCCESS; } while (datalen-- > 0) { @@ -82,7 +82,7 @@ int32_t tc_sha256_update(TCSha256State_t s, const uint8_t *data, size_t datalen) } } - return TC_SUCCESS; + return TC_CRYPTO_SUCCESS; } int32_t tc_sha256_final(uint8_t *digest, TCSha256State_t s) @@ -93,7 +93,7 @@ int32_t tc_sha256_final(uint8_t *digest, TCSha256State_t s) if (digest == (uint8_t *) 0 || s == (TCSha256State_t) 0 || s->iv == (uint32_t *) 0) { - return TC_FAIL; + return TC_CRYPTO_FAIL; } s->bits_hashed += (s->leftover_offset << 3); @@ -134,7 +134,7 @@ int32_t tc_sha256_final(uint8_t *digest, TCSha256State_t s) /* destroy the current state */ _set(s, 0, sizeof(*s)); - return TC_SUCCESS; + return TC_CRYPTO_SUCCESS; } /* diff --git a/ext/lib/crypto/tinycrypt/source/utils.c b/ext/lib/crypto/tinycrypt/source/utils.c index 7f05939e2..3338e0ca4 100644 --- a/ext/lib/crypto/tinycrypt/source/utils.c +++ b/ext/lib/crypto/tinycrypt/source/utils.c @@ -45,7 +45,7 @@ uint32_t _copy(uint8_t *to, uint32_t to_len, (void)memcpy(to, from, from_len); return from_len; } else { - return TC_FAIL; + return TC_CRYPTO_FAIL; } } |