diff --git a/features/mbedtls/mbed-crypto/VERSION.txt b/features/mbedtls/mbed-crypto/VERSION.txt index d73ec64702..20ff92fea1 100644 --- a/features/mbedtls/mbed-crypto/VERSION.txt +++ b/features/mbedtls/mbed-crypto/VERSION.txt @@ -1 +1 @@ -mbedcrypto-2.0.0 +mbedcrypto-2.1.0d0 diff --git a/features/mbedtls/mbed-crypto/importer/Makefile b/features/mbedtls/mbed-crypto/importer/Makefile index cd58e4c3ae..74b65784ce 100644 --- a/features/mbedtls/mbed-crypto/importer/Makefile +++ b/features/mbedtls/mbed-crypto/importer/Makefile @@ -29,7 +29,7 @@ # Set the Mbed Crypto release to import (this can/should be edited before # import) -CRYPTO_RELEASE ?= mbedcrypto-2.0.0 +CRYPTO_RELEASE ?= mbedcrypto-2.1.0d0 CRYPTO_REPO_URL ?= git@github.com:ARMmbed/mbedtls-psa.git # Translate between Mbed Crypto namespace and Mbed OS namespace diff --git a/features/mbedtls/mbed-crypto/inc/mbedtls/asn1.h b/features/mbedtls/mbed-crypto/inc/mbedtls/asn1.h index ab947ab7ef..1a76111684 100644 --- a/features/mbedtls/mbed-crypto/inc/mbedtls/asn1.h +++ b/features/mbedtls/mbed-crypto/inc/mbedtls/asn1.h @@ -52,7 +52,7 @@ #define MBEDTLS_ERR_ASN1_UNEXPECTED_TAG -0x0062 /**< ASN1 tag was of an unexpected value. */ #define MBEDTLS_ERR_ASN1_INVALID_LENGTH -0x0064 /**< Error when trying to determine the length or invalid length. */ #define MBEDTLS_ERR_ASN1_LENGTH_MISMATCH -0x0066 /**< Actual length differs from expected length. */ -#define MBEDTLS_ERR_ASN1_INVALID_DATA -0x0068 /**< Data is invalid. (not used) */ +#define MBEDTLS_ERR_ASN1_INVALID_DATA -0x0068 /**< Data is invalid. */ #define MBEDTLS_ERR_ASN1_ALLOC_FAILED -0x006A /**< Memory allocation failed */ #define MBEDTLS_ERR_ASN1_BUF_TOO_SMALL -0x006C /**< Buffer too small when writing ASN.1 data structure. */ @@ -176,119 +176,203 @@ mbedtls_asn1_named_data; * \brief Get the length of an ASN.1 element. * Updates the pointer to immediately behind the length. * - * \param p The position in the ASN.1 data - * \param end End of data - * \param len The variable that will receive the value + * \param p On entry, \c *p points to the first byte of the length, + * i.e. immediately after the tag. + * On successful completion, \c *p points to the first byte + * after the length, i.e. the first byte of the content. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param len On successful completion, \c *len contains the length + * read from the ASN.1 input. * - * \return 0 if successful, MBEDTLS_ERR_ASN1_OUT_OF_DATA on reaching - * end of data, MBEDTLS_ERR_ASN1_INVALID_LENGTH if length is - * unparseable. + * \return 0 if successful. + * \return #MBEDTLS_ERR_ASN1_OUT_OF_DATA if the ASN.1 element + * would end beyond \p end. + * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparseable. */ int mbedtls_asn1_get_len( unsigned char **p, - const unsigned char *end, - size_t *len ); + const unsigned char *end, + size_t *len ); /** - * \brief Get the tag and length of the tag. Check for the requested tag. + * \brief Get the tag and length of the element. + * Check for the requested tag. * Updates the pointer to immediately behind the tag and length. * - * \param p The position in the ASN.1 data - * \param end End of data - * \param len The variable that will receive the length - * \param tag The expected tag + * \param p On entry, \c *p points to the start of the ASN.1 element. + * On successful completion, \c *p points to the first byte + * after the length, i.e. the first byte of the content. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param len On successful completion, \c *len contains the length + * read from the ASN.1 input. + * \param tag The expected tag. * - * \return 0 if successful, MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if tag did - * not match requested tag, or another specific ASN.1 error code. + * \return 0 if successful. + * \return #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the data does not start + * with the requested tag. + * \return #MBEDTLS_ERR_ASN1_OUT_OF_DATA if the ASN.1 element + * would end beyond \p end. + * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparseable. */ int mbedtls_asn1_get_tag( unsigned char **p, - const unsigned char *end, - size_t *len, int tag ); + const unsigned char *end, + size_t *len, int tag ); /** * \brief Retrieve a boolean ASN.1 tag and its value. * Updates the pointer to immediately behind the full tag. * - * \param p The position in the ASN.1 data - * \param end End of data - * \param val The variable that will receive the value + * \param p On entry, \c *p points to the start of the ASN.1 element. + * On successful completion, \c *p points to the first byte + * beyond the ASN.1 element. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param val On success, the parsed value (\c 0 or \c 1). * - * \return 0 if successful or a specific ASN.1 error code. + * \return 0 if successful. + * \return An ASN.1 error code if the input does not start with + * a valid ASN.1 BOOLEAN. */ int mbedtls_asn1_get_bool( unsigned char **p, - const unsigned char *end, - int *val ); + const unsigned char *end, + int *val ); /** * \brief Retrieve an integer ASN.1 tag and its value. * Updates the pointer to immediately behind the full tag. * - * \param p The position in the ASN.1 data - * \param end End of data - * \param val The variable that will receive the value + * \param p On entry, \c *p points to the start of the ASN.1 element. + * On successful completion, \c *p points to the first byte + * beyond the ASN.1 element. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param val On success, the parsed value. * - * \return 0 if successful or a specific ASN.1 error code. + * \return 0 if successful. + * \return An ASN.1 error code if the input does not start with + * a valid ASN.1 INTEGER. + * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does + * not fit in an \c int. + * \return An ASN.1 error code if the input does not start with + * a valid ASN.1 INTEGER. */ int mbedtls_asn1_get_int( unsigned char **p, - const unsigned char *end, - int *val ); + const unsigned char *end, + int *val ); /** * \brief Retrieve a bitstring ASN.1 tag and its value. * Updates the pointer to immediately behind the full tag. * - * \param p The position in the ASN.1 data - * \param end End of data - * \param bs The variable that will receive the value + * \param p On entry, \c *p points to the start of the ASN.1 element. + * On successful completion, \c *p is equal to \p end. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param bs On success, ::mbedtls_asn1_bitstring information about + * the parsed value. * - * \return 0 if successful or a specific ASN.1 error code. + * \return 0 if successful. + * \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input contains + * extra data after a valid BIT STRING. + * \return An ASN.1 error code if the input does not start with + * a valid ASN.1 BIT STRING. */ int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end, - mbedtls_asn1_bitstring *bs); + mbedtls_asn1_bitstring *bs ); /** * \brief Retrieve a bitstring ASN.1 tag without unused bits and its * value. * Updates the pointer to the beginning of the bit/octet string. * - * \param p The position in the ASN.1 data - * \param end End of data - * \param len Length of the actual bit/octect string in bytes + * \param p On entry, \c *p points to the start of the ASN.1 element. + * On successful completion, \c *p points to the first byte + * of the content of the BIT STRING. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param len On success, \c *len is the length of the content in bytes. * - * \return 0 if successful or a specific ASN.1 error code. + * \return 0 if successful. + * \return #MBEDTLS_ERR_ASN1_INVALID_DATA if the input starts with + * a valid BIT STRING with a nonzero number of unused bits. + * \return An ASN.1 error code if the input does not start with + * a valid ASN.1 BIT STRING. */ -int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end, - size_t *len ); +int mbedtls_asn1_get_bitstring_null( unsigned char **p, + const unsigned char *end, + size_t *len ); /** - * \brief Parses and splits an ASN.1 "SEQUENCE OF " - * Updated the pointer to immediately behind the full sequence tag. + * \brief Parses and splits an ASN.1 "SEQUENCE OF ". + * Updates the pointer to immediately behind the full sequence tag. * - * \param p The position in the ASN.1 data - * \param end End of data - * \param cur First variable in the chain to fill - * \param tag Type of sequence + * \note On error, this function may return a partial list in \p cur. + * You must set `cur->next = NULL` before calling this function! + * Otherwise it is impossible to distinguish a previously non-null + * pointer from a pointer to an object allocated by this function. * - * \return 0 if successful or a specific ASN.1 error code. + * \note If the sequence is empty, this function does not modify + * \c *cur. If the sequence is valid and non-empty, this + * function sets `cur->buf.tag` to \p tag. This allows + * callers to distinguish between an empty sequence and + * a one-element sequence. + * + * \param p On entry, \c *p points to the start of the ASN.1 element. + * On successful completion, \c *p is equal to \p end. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param cur A ::mbedtls_asn1_sequence which this function fills. + * When this function returns, \c *cur is the head of a linked + * list. Each node in this list is allocated with + * mbedtls_calloc() apart from \p cur itself, and should + * therefore be freed with mbedtls_free(). + * The list describes the content of the sequence. + * The head of the list (i.e. \c *cur itself) describes the + * first element, `*cur->next` describes the second element, etc. + * For each element, `buf.tag == tag`, `buf.len` is the length + * of the content of the content of the element, and `buf.p` + * points to the first byte of the content (i.e. immediately + * past the length of the element). + * Note that list elements may be allocated even on error. + * \param tag Each element of the sequence must have this tag. + * + * \return 0 if successful. + * \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input contains + * extra data after a valid SEQUENCE OF \p tag. + * \return #MBEDTLS_ERR_ASN1_ALLOC_FAILED if a memory allocation failed. + * \return An ASN.1 error code if the input does not start with + * a valid ASN.1 BIT STRING. */ int mbedtls_asn1_get_sequence_of( unsigned char **p, - const unsigned char *end, - mbedtls_asn1_sequence *cur, - int tag); + const unsigned char *end, + mbedtls_asn1_sequence *cur, + int tag ); #if defined(MBEDTLS_BIGNUM_C) /** - * \brief Retrieve a MPI value from an integer ASN.1 tag. + * \brief Retrieve an integer ASN.1 tag and its value. * Updates the pointer to immediately behind the full tag. * - * \param p The position in the ASN.1 data - * \param end End of data - * \param X The MPI that will receive the value + * \param p On entry, \c *p points to the start of the ASN.1 element. + * On successful completion, \c *p points to the first byte + * beyond the ASN.1 element. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param X On success, the parsed value. * - * \return 0 if successful or a specific ASN.1 or MPI error code. + * \return 0 if successful. + * \return An ASN.1 error code if the input does not start with + * a valid ASN.1 INTEGER. + * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does + * not fit in an \c int. + * \return An MPI error code if the parsed value is too large. + * \return An ASN.1 error code if the input does not start with + * a valid ASN.1 INTEGER. */ int mbedtls_asn1_get_mpi( unsigned char **p, - const unsigned char *end, - mbedtls_mpi *X ); + const unsigned char *end, + mbedtls_mpi *X ); #endif /* MBEDTLS_BIGNUM_C */ /** @@ -296,10 +380,14 @@ int mbedtls_asn1_get_mpi( unsigned char **p, * Updates the pointer to immediately behind the full * AlgorithmIdentifier. * - * \param p The position in the ASN.1 data - * \param end End of data - * \param alg The buffer to receive the OID - * \param params The buffer to receive the params (if any) + * \param p On entry, \c *p points to the start of the ASN.1 element. + * On successful completion, \c *p points to the first byte + * beyond the AlgorithmIdentifier element. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param alg The buffer to receive the OID. + * \param params The buffer to receive the parameters. + * This is zeroized if there are no parameters. * * \return 0 if successful or a specific ASN.1 or MPI error code. */ @@ -313,9 +401,12 @@ int mbedtls_asn1_get_alg( unsigned char **p, * Updates the pointer to immediately behind the full * AlgorithmIdentifier. * - * \param p The position in the ASN.1 data - * \param end End of data - * \param alg The buffer to receive the OID + * \param p On entry, \c *p points to the start of the ASN.1 element. + * On successful completion, \c *p points to the first byte + * beyond the AlgorithmIdentifier element. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param alg The buffer to receive the OID. * * \return 0 if successful or a specific ASN.1 or MPI error code. */ @@ -339,15 +430,19 @@ mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data * /** * \brief Free a mbedtls_asn1_named_data entry * - * \param entry The named data entry to free + * \param entry The named data entry to free. + * This function calls mbedtls_free() on + * `entry->oid.p` and `entry->val.p`. */ void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *entry ); /** - * \brief Free all entries in a mbedtls_asn1_named_data list - * Head will be set to NULL + * \brief Free all entries in a mbedtls_asn1_named_data list. * - * \param head Pointer to the head of the list of named data entries to free + * \param head Pointer to the head of the list of named data entries to free. + * This function calls mbedtls_asn1_free_named_data() and + * mbedtls_free() on each list element and + * sets \c *head to \c NULL. */ void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head ); diff --git a/features/mbedtls/mbed-crypto/inc/mbedtls/asn1write.h b/features/mbedtls/mbed-crypto/inc/mbedtls/asn1write.h index 336f2daf1b..982414626e 100644 --- a/features/mbedtls/mbed-crypto/inc/mbedtls/asn1write.h +++ b/features/mbedtls/mbed-crypto/inc/mbedtls/asn1write.h @@ -100,6 +100,7 @@ int mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start, * \param p The reference to the current position pointer. * \param start The start of the buffer, for bounds-checking. * \param X The MPI to write. + * It must be non-negative. * * \return The number of bytes written to \p p on success. * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. @@ -184,6 +185,7 @@ int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start, * \param p The reference to the current position pointer. * \param start The start of the buffer, for bounds-checking. * \param val The integer value to write. + * It must be non-negative. * * \return The number of bytes written to \p p on success. * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. @@ -232,7 +234,7 @@ int mbedtls_asn1_write_printable_string( unsigned char **p, /** * \brief Write a UTF8 string in ASN.1 format using the UTF8String - * string encoding tag (#MBEDTLS_ASN1_PRINTABLE_STRING). + * string encoding tag (#MBEDTLS_ASN1_UTF8_STRING). * * \note This function works backwards in data buffer. * @@ -332,9 +334,13 @@ int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start, * through (will be updated in case of a new entry). * \param oid The OID to look for. * \param oid_len The size of the OID. - * \param val The data to store (can be \c NULL if you want to fill - * it by hand). + * \param val The associated data to store. If this is \c NULL, + * no data is copied to the new or existing buffer. * \param val_len The minimum length of the data buffer needed. + * If this is 0, do not allocate a buffer for the associated + * data. + * If the OID was already present, enlarge, shrink or free + * the existing buffer to fit \p val_len. * * \return A pointer to the new / existing entry on success. * \return \c NULL if if there was a memory allocation error. diff --git a/features/mbedtls/mbed-crypto/inc/mbedtls/ctr_drbg.h b/features/mbedtls/mbed-crypto/inc/mbedtls/ctr_drbg.h index ffaf8ad79d..2db4021336 100644 --- a/features/mbedtls/mbed-crypto/inc/mbedtls/ctr_drbg.h +++ b/features/mbedtls/mbed-crypto/inc/mbedtls/ctr_drbg.h @@ -1,7 +1,8 @@ /** * \file ctr_drbg.h * - * \brief This file contains CTR_DRBG definitions and functions. + * \brief This file contains definitions and functions for the + * CTR_DRBG pseudorandom generator. * * CTR_DRBG is a standardized way of building a PRNG from a block-cipher * in counter mode operation, as defined in NIST SP 800-90A: @@ -9,13 +10,35 @@ * Bit Generators. * * The Mbed TLS implementation of CTR_DRBG uses AES-256 (default) or AES-128 - * as the underlying block cipher. + * (if \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled at compile time) + * as the underlying block cipher, with a derivation function. + * The initial seeding grabs #MBEDTLS_CTR_DRBG_ENTROPY_LEN bytes of entropy. + * See the documentation of mbedtls_ctr_drbg_seed() for more details. * - * \warning Using 128-bit keys for CTR_DRBG limits the security of generated - * keys and operations that use random values generated to 128-bit security. + * Based on NIST SP 800-90A §10.2.1 table 3 and NIST SP 800-57 part 1 table 2, + * here are the security strengths achieved in typical configuration: + * - 256 bits under the default configuration of the library, with AES-256 + * and with #MBEDTLS_CTR_DRBG_ENTROPY_LEN set to 48 or more. + * - 256 bits if AES-256 is used, #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set + * to 32 or more, and the DRBG is initialized with an explicit + * nonce in the \c custom parameter to mbedtls_ctr_drbg_seed(). + * - 128 bits if AES-256 is used but #MBEDTLS_CTR_DRBG_ENTROPY_LEN is + * between 24 and 47 and the DRBG is not initialized with an explicit + * nonce (see mbedtls_ctr_drbg_seed()). + * - 128 bits if AES-128 is used (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY enabled) + * and #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set to 24 or more (which is + * always the case unless it is explicitly set to a different value + * in config.h). + * + * Note that the value of #MBEDTLS_CTR_DRBG_ENTROPY_LEN defaults to: + * - \c 48 if the module \c MBEDTLS_SHA512_C is enabled and the symbol + * \c MBEDTLS_ENTROPY_FORCE_SHA256 is disabled at compile time. + * This is the default configuration of the library. + * - \c 32 if the module \c MBEDTLS_SHA512_C is disabled at compile time. + * - \c 32 if \c MBEDTLS_ENTROPY_FORCE_SHA256 is enabled at compile time. */ /* - * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved + * Copyright (C) 2006-2019, Arm Limited (or its affiliates), All Rights Reserved * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -56,9 +79,19 @@ #define MBEDTLS_CTR_DRBG_BLOCKSIZE 16 /**< The block size used by the cipher. */ #if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) -#define MBEDTLS_CTR_DRBG_KEYSIZE 16 /**< The key size used by the cipher (compile-time choice: 128 bits). */ +#define MBEDTLS_CTR_DRBG_KEYSIZE 16 +/**< The key size in bytes used by the cipher. + * + * Compile-time choice: 16 bytes (128 bits) + * because #MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled. + */ #else -#define MBEDTLS_CTR_DRBG_KEYSIZE 32 /**< The key size used by the cipher (compile-time choice: 256 bits). */ +#define MBEDTLS_CTR_DRBG_KEYSIZE 32 +/**< The key size in bytes used by the cipher. + * + * Compile-time choice: 32 bytes (256 bits) + * because \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is disabled. + */ #endif #define MBEDTLS_CTR_DRBG_KEYBITS ( MBEDTLS_CTR_DRBG_KEYSIZE * 8 ) /**< The key size for the DRBG operation, in bits. */ @@ -73,21 +106,31 @@ * \{ */ +/** \def MBEDTLS_CTR_DRBG_ENTROPY_LEN + * + * \brief The amount of entropy used per seed by default, in bytes. + */ #if !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) #if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) +/** This is 48 bytes because the entropy module uses SHA-512 + * (\c MBEDTLS_ENTROPY_FORCE_SHA256 is disabled). + */ #define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 -/**< The amount of entropy used per seed by default: - * + +#else /* defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) */ + +/** This is 32 bytes because the entropy module uses SHA-256 + * (the SHA512 module is disabled or + * \c MBEDTLS_ENTROPY_FORCE_SHA256 is enabled). */ -#else +#if !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) +/** \warning To achieve a 256-bit security strength, you must pass a nonce + * to mbedtls_ctr_drbg_seed(). + */ +#endif /* !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) */ #define MBEDTLS_CTR_DRBG_ENTROPY_LEN 32 -/**< Amount of entropy used per seed by default: - * - */ -#endif -#endif +#endif /* defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) */ +#endif /* !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) */ #if !defined(MBEDTLS_CTR_DRBG_RESEED_INTERVAL) #define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 @@ -106,7 +149,7 @@ #if !defined(MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) #define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 -/**< The maximum size of seed or reseed buffer. */ +/**< The maximum size of seed or reseed buffer in bytes. */ #endif /* \} name SECTION: Module settings */ @@ -164,17 +207,62 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ); * \brief This function seeds and sets up the CTR_DRBG * entropy source for future reseeds. * - * \note Personalization data can be provided in addition to the more generic - * entropy source, to make this instantiation as unique as possible. + * A typical choice for the \p f_entropy and \p p_entropy parameters is + * to use the entropy module: + * - \p f_entropy is mbedtls_entropy_func(); + * - \p p_entropy is an instance of ::mbedtls_entropy_context initialized + * with mbedtls_entropy_init() (which registers the platform's default + * entropy sources). * + * \p f_entropy is always called with a buffer size equal to the entropy + * length. The entropy length is initially #MBEDTLS_CTR_DRBG_ENTROPY_LEN + * and this value is always used for the initial seeding. You can change + * the entropy length for subsequent seeding by calling + * mbedtls_ctr_drbg_set_entropy_len() after this function. + * + * You can provide a personalization string in addition to the + * entropy source, to make this instantiation as unique as possible. + * + * \note The _seed_material_ value passed to the derivation + * function in the CTR_DRBG Instantiate Process + * described in NIST SP 800-90A §10.2.1.3.2 + * is the concatenation of the string obtained from + * calling \p f_entropy and the \p custom string. + * The origin of the nonce depends on the value of + * the entropy length relative to the security strength. + * - If the entropy length is at least 1.5 times the + * security strength then the nonce is taken from the + * string obtained with \p f_entropy. + * - If the entropy length is less than the security + * strength, then the nonce is taken from \p custom. + * In this case, for compliance with SP 800-90A, + * you must pass a unique value of \p custom at + * each invocation. See SP 800-90A §8.6.7 for more + * details. + */ +#if MBEDTLS_CTR_DRBG_ENTROPY_LEN < MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2 +/** \warning When #MBEDTLS_CTR_DRBG_ENTROPY_LEN is less than + * #MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2, to achieve the + * maximum security strength permitted by CTR_DRBG, + * you must pass a value of \p custom that is a nonce: + * this value must never be repeated in subsequent + * runs of the same application or on a different + * device. + */ +#endif +/** * \param ctx The CTR_DRBG context to seed. * \param f_entropy The entropy callback, taking as arguments the * \p p_entropy context, the buffer to fill, and the - length of the buffer. - * \param p_entropy The entropy context. - * \param custom Personalization data, that is device-specific - identifiers. Can be NULL. - * \param len The length of the personalization data. + * length of the buffer. + * \param p_entropy The entropy context to pass to \p f_entropy. + * \param custom The personalization string. + * This can be \c NULL, in which case the personalization + * string is empty regardless of the value of \p len. + * \param len The length of the personalization string. + * This must be at most + * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + * - #MBEDTLS_CTR_DRBG_ENTROPY_LEN. * * \return \c 0 on success. * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure. @@ -197,7 +285,8 @@ void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx ); * The default value is off. * * \note If enabled, entropy is gathered at the beginning of - * every call to mbedtls_ctr_drbg_random_with_add(). + * every call to mbedtls_ctr_drbg_random_with_add() + * or mbedtls_ctr_drbg_random(). * Only use this if your entropy source has sufficient * throughput. * @@ -209,18 +298,42 @@ void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, /** * \brief This function sets the amount of entropy grabbed on each - * seed or reseed. The default value is - * #MBEDTLS_CTR_DRBG_ENTROPY_LEN. + * subsequent reseed. + * + * The default value is #MBEDTLS_CTR_DRBG_ENTROPY_LEN. + * + * \note mbedtls_ctr_drbg_seed() always sets the entropy length + * to #MBEDTLS_CTR_DRBG_ENTROPY_LEN, so this function + * only has an effect when it is called after + * mbedtls_ctr_drbg_seed(). + * + * \note The security strength of CTR_DRBG is bounded by the + * entropy length. Thus: + * - When using AES-256 + * (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is disabled, + * which is the default), + * \p len must be at least 32 (in bytes) + * to achieve a 256-bit strength. + * - When using AES-128 + * (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled) + * \p len must be at least 16 (in bytes) + * to achieve a 128-bit strength. * * \param ctx The CTR_DRBG context. - * \param len The amount of entropy to grab. + * \param len The amount of entropy to grab, in bytes. + * This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT. */ void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx, size_t len ); /** * \brief This function sets the reseed interval. - * The default value is #MBEDTLS_CTR_DRBG_RESEED_INTERVAL. + * + * The reseed interval is the number of calls to mbedtls_ctr_drbg_random() + * or mbedtls_ctr_drbg_random_with_add() after which the entropy function + * is called again. + * + * The default value is #MBEDTLS_CTR_DRBG_RESEED_INTERVAL. * * \param ctx The CTR_DRBG context. * \param interval The reseed interval. @@ -233,8 +346,12 @@ void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx, * extracts data from the entropy source. * * \param ctx The CTR_DRBG context. - * \param additional Additional data to add to the state. Can be NULL. + * \param additional Additional data to add to the state. Can be \c NULL. * \param len The length of the additional data. + * This must be less than + * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len + * where \c entropy_len is the entropy length + * configured for the context. * * \return \c 0 on success. * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure. @@ -246,7 +363,8 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx, * \brief This function updates the state of the CTR_DRBG context. * * \param ctx The CTR_DRBG context. - * \param additional The data to update the state with. + * \param additional The data to update the state with. This must not be + * \c NULL unless \p add_len is \c 0. * \param add_len Length of \p additional in bytes. This must be at * most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT. * @@ -264,14 +382,23 @@ int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx, * \brief This function updates a CTR_DRBG instance with additional * data and uses it to generate random data. * - * \note The function automatically reseeds if the reseed counter is exceeded. + * This function automatically reseeds if the reseed counter is exceeded + * or prediction resistance is enabled. * * \param p_rng The CTR_DRBG context. This must be a pointer to a * #mbedtls_ctr_drbg_context structure. * \param output The buffer to fill. - * \param output_len The length of the buffer. - * \param additional Additional data to update. Can be NULL. - * \param add_len The length of the additional data. + * \param output_len The length of the buffer in bytes. + * \param additional Additional data to update. Can be \c NULL, in which + * case the additional data is empty regardless of + * the value of \p add_len. + * \param add_len The length of the additional data + * if \p additional is not \c NULL. + * This must be less than #MBEDTLS_CTR_DRBG_MAX_INPUT + * and less than + * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len + * where \c entropy_len is the entropy length + * configured for the context. * * \return \c 0 on success. * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or @@ -284,12 +411,14 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng, /** * \brief This function uses CTR_DRBG to generate random data. * - * \note The function automatically reseeds if the reseed counter is exceeded. + * This function automatically reseeds if the reseed counter is exceeded + * or prediction resistance is enabled. + * * * \param p_rng The CTR_DRBG context. This must be a pointer to a * #mbedtls_ctr_drbg_context structure. * \param output The buffer to fill. - * \param output_len The length of the buffer. + * \param output_len The length of the buffer in bytes. * * \return \c 0 on success. * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or @@ -336,7 +465,7 @@ MBEDTLS_DEPRECATED void mbedtls_ctr_drbg_update( * * \return \c 0 on success. * \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error. - * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on + * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on reseed * failure. */ int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ); @@ -350,8 +479,10 @@ int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char * * \return \c 0 on success. * \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error. - * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or - * #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG on failure. + * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on + * reseed failure. + * \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if the existing + * seed file is too large. */ int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ); #endif /* MBEDTLS_FS_IO */ diff --git a/features/mbedtls/mbed-crypto/inc/mbedtls/hmac_drbg.h b/features/mbedtls/mbed-crypto/inc/mbedtls/hmac_drbg.h index 46536a1f44..519d692fba 100644 --- a/features/mbedtls/mbed-crypto/inc/mbedtls/hmac_drbg.h +++ b/features/mbedtls/mbed-crypto/inc/mbedtls/hmac_drbg.h @@ -1,10 +1,14 @@ /** * \file hmac_drbg.h * - * \brief HMAC_DRBG (NIST SP 800-90A) + * \brief The HMAC_DRBG pseudorandom generator. + * + * This module implements the HMAC_DRBG pseudorandom generator described + * in NIST SP 800-90A: Recommendation for Random Number Generation Using + * Deterministic Random Bit Generators. */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright (C) 2006-2019, ARM Limited, All Rights Reserved * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -104,38 +108,74 @@ typedef struct mbedtls_hmac_drbg_context } mbedtls_hmac_drbg_context; /** - * \brief HMAC_DRBG context initialization - * Makes the context ready for mbedtls_hmac_drbg_seed(), - * mbedtls_hmac_drbg_seed_buf() or - * mbedtls_hmac_drbg_free(). + * \brief HMAC_DRBG context initialization. * - * \param ctx HMAC_DRBG context to be initialized + * This function makes the context ready for mbedtls_hmac_drbg_seed(), + * mbedtls_hmac_drbg_seed_buf() or mbedtls_hmac_drbg_free(). + * + * \param ctx HMAC_DRBG context to be initialized. */ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx ); /** - * \brief HMAC_DRBG initial seeding - * Seed and setup entropy source for future reseeds. + * \brief HMAC_DRBG initial seeding. * - * \param ctx HMAC_DRBG context to be seeded - * \param md_info MD algorithm to use for HMAC_DRBG - * \param f_entropy Entropy callback (p_entropy, buffer to fill, buffer - * length) - * \param p_entropy Entropy context - * \param custom Personalization data (Device specific identifiers) - * (Can be NULL) - * \param len Length of personalization data + * Set the initial seed and set up the entropy source for future reseeds. * - * \note The "security strength" as defined by NIST is set to: - * 128 bits if md_alg is SHA-1, - * 192 bits if md_alg is SHA-224, - * 256 bits if md_alg is SHA-256 or higher. + * A typical choice for the \p f_entropy and \p p_entropy parameters is + * to use the entropy module: + * - \p f_entropy is mbedtls_entropy_func(); + * - \p p_entropy is an instance of ::mbedtls_entropy_context initialized + * with mbedtls_entropy_init() (which registers the platform's default + * entropy sources). + * + * You can provide a personalization string in addition to the + * entropy source, to make this instantiation as unique as possible. + * + * \note By default, the security strength as defined by NIST is: + * - 128 bits if \p md_info is SHA-1; + * - 192 bits if \p md_info is SHA-224; + * - 256 bits if \p md_info is SHA-256, SHA-384 or SHA-512. * Note that SHA-256 is just as efficient as SHA-224. + * The security strength can be reduced if a smaller + * entropy length is set with + * mbedtls_hmac_drbg_set_entropy_len() afterwards. * - * \return 0 if successful, or - * MBEDTLS_ERR_MD_BAD_INPUT_DATA, or - * MBEDTLS_ERR_MD_ALLOC_FAILED, or - * MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED. + * \note The entropy length for the initial seeding is + * the security strength (converted from bits to bytes). + * You can set a different entropy length for subsequent + * seeding by calling mbedtls_hmac_drbg_set_entropy_len() + * after this function. + * + * \note During the initial seeding, this function calls + * the entropy source to obtain a nonce + * whose length is half the entropy length. + * + * \param ctx HMAC_DRBG context to be seeded. + * \param md_info MD algorithm to use for HMAC_DRBG. + * \param f_entropy The entropy callback, taking as arguments the + * \p p_entropy context, the buffer to fill, and the + * length of the buffer. + * \p f_entropy is always called with a length that is + * less than or equal to the entropy length. + * \param p_entropy The entropy context to pass to \p f_entropy. + * \param custom The personalization string. + * This can be \c NULL, in which case the personalization + * string is empty regardless of the value of \p len. + * \param len The length of the personalization string. + * This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT + * and also at most + * #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \p entropy_len * 3 / 2 + * where \p entropy_len is the entropy length + * described above. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is + * invalid. + * \return #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough + * memory to allocate context data. + * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED + * if the call to \p f_entropy failed. */ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx, const mbedtls_md_info_t * md_info, @@ -146,98 +186,136 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx, /** * \brief Initilisation of simpified HMAC_DRBG (never reseeds). - * (For use with deterministic ECDSA.) * - * \param ctx HMAC_DRBG context to be initialised - * \param md_info MD algorithm to use for HMAC_DRBG - * \param data Concatenation of entropy string and additional data - * \param data_len Length of data in bytes + * This function is meant for use in algorithms that need a pseudorandom + * input such as deterministic ECDSA. * - * \return 0 if successful, or - * MBEDTLS_ERR_MD_BAD_INPUT_DATA, or - * MBEDTLS_ERR_MD_ALLOC_FAILED. + * \param ctx HMAC_DRBG context to be initialised. + * \param md_info MD algorithm to use for HMAC_DRBG. + * \param data Concatenation of the initial entropy string and + * the additional data. + * \param data_len Length of \p data in bytes. + * + * \return \c 0 if successful. or + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is + * invalid. + * \return #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough + * memory to allocate context data. */ int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx, const mbedtls_md_info_t * md_info, const unsigned char *data, size_t data_len ); /** - * \brief Enable / disable prediction resistance (Default: Off) + * \brief This function turns prediction resistance on or off. + * The default value is off. * - * Note: If enabled, entropy is used for ctx->entropy_len before each call! - * Only use this if you have ample supply of good entropy! + * \note If enabled, entropy is gathered at the beginning of + * every call to mbedtls_hmac_drbg_random_with_add() + * or mbedtls_hmac_drbg_random(). + * Only use this if your entropy source has sufficient + * throughput. * - * \param ctx HMAC_DRBG context - * \param resistance MBEDTLS_HMAC_DRBG_PR_ON or MBEDTLS_HMAC_DRBG_PR_OFF + * \param ctx The HMAC_DRBG context. + * \param resistance #MBEDTLS_HMAC_DRBG_PR_ON or #MBEDTLS_HMAC_DRBG_PR_OFF. */ void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx, int resistance ); /** - * \brief Set the amount of entropy grabbed on each reseed - * (Default: given by the security strength, which - * depends on the hash used, see \c mbedtls_hmac_drbg_init() ) + * \brief This function sets the amount of entropy grabbed on each + * reseed. * - * \param ctx HMAC_DRBG context - * \param len Amount of entropy to grab, in bytes + * The default value is set by mbedtls_hmac_drbg_seed(). + * + * \note mbedtls_hmac_drbg_seed() always sets the entropy length + * to the default value based on the chosen MD algorithm, + * so this function only has an effect if it is called + * after mbedtls_hmac_drbg_seed(). + * + * \param ctx The HMAC_DRBG context. + * \param len The amount of entropy to grab, in bytes. */ void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len ); /** - * \brief Set the reseed interval - * (Default: MBEDTLS_HMAC_DRBG_RESEED_INTERVAL) + * \brief Set the reseed interval. * - * \param ctx HMAC_DRBG context - * \param interval Reseed interval + * The reseed interval is the number of calls to mbedtls_hmac_drbg_random() + * or mbedtls_hmac_drbg_random_with_add() after which the entropy function + * is called again. + * + * The default value is #MBEDTLS_HMAC_DRBG_RESEED_INTERVAL. + * + * \param ctx The HMAC_DRBG context. + * \param interval The reseed interval. */ void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval ); /** - * \brief HMAC_DRBG update state + * \brief This function updates the state of the HMAC_DRBG context. * - * \param ctx HMAC_DRBG context - * \param additional Additional data to update state with, or NULL - * \param add_len Length of additional data, or 0 + * \param ctx The HMAC_DRBG context. + * \param additional The data to update the state with. + * If this is \c NULL, there is no additional data. + * \param add_len Length of \p additional in bytes. + * Unused if \p additional is \c NULL. * * \return \c 0 on success, or an error from the underlying * hash calculation. - * - * \note Additional data is optional, pass NULL and 0 as second - * third argument if no additional data is being used. */ int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx, const unsigned char *additional, size_t add_len ); /** - * \brief HMAC_DRBG reseeding (extracts data from entropy source) + * \brief This function reseeds the HMAC_DRBG context, that is + * extracts data from the entropy source. * - * \param ctx HMAC_DRBG context - * \param additional Additional data to add to state (Can be NULL) - * \param len Length of additional data + * \param ctx The HMAC_DRBG context. + * \param additional Additional data to add to the state. + * If this is \c NULL, there is no additional data + * and \p len should be \c 0. + * \param len The length of the additional data. + * This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT + * and also at most + * #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \p entropy_len + * where \p entropy_len is the entropy length + * (see mbedtls_hmac_drbg_set_entropy_len()). * - * \return 0 if successful, or - * MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED + * if a call to the entropy function failed. */ int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx, const unsigned char *additional, size_t len ); /** - * \brief HMAC_DRBG generate random with additional update input + * \brief This function updates an HMAC_DRBG instance with additional + * data and uses it to generate random data. * - * Note: Automatically reseeds if reseed_counter is reached or PR is enabled. + * This function automatically reseeds if the reseed counter is exceeded + * or prediction resistance is enabled. * - * \param p_rng HMAC_DRBG context - * \param output Buffer to fill - * \param output_len Length of the buffer - * \param additional Additional data to update with (can be NULL) - * \param add_len Length of additional data (can be 0) + * \param p_rng The HMAC_DRBG context. This must be a pointer to a + * #mbedtls_hmac_drbg_context structure. + * \param output The buffer to fill. + * \param output_len The length of the buffer in bytes. + * This must be at most #MBEDTLS_HMAC_DRBG_MAX_REQUEST. + * \param additional Additional data to update with. + * If this is \c NULL, there is no additional data + * and \p add_len should be \c 0. + * \param add_len The length of the additional data. + * This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT. * - * \return 0 if successful, or - * MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED, or - * MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG, or - * MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG. + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED + * if a call to the entropy source failed. + * \return #MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG if + * \p output_len > #MBEDTLS_HMAC_DRBG_MAX_REQUEST. + * \return #MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG if + * \p add_len > #MBEDTLS_HMAC_DRBG_MAX_INPUT. */ int mbedtls_hmac_drbg_random_with_add( void *p_rng, unsigned char *output, size_t output_len, @@ -245,24 +323,29 @@ int mbedtls_hmac_drbg_random_with_add( void *p_rng, size_t add_len ); /** - * \brief HMAC_DRBG generate random + * \brief This function uses HMAC_DRBG to generate random data. * - * Note: Automatically reseeds if reseed_counter is reached or PR is enabled. + * This function automatically reseeds if the reseed counter is exceeded + * or prediction resistance is enabled. * - * \param p_rng HMAC_DRBG context - * \param output Buffer to fill - * \param out_len Length of the buffer + * \param p_rng The HMAC_DRBG context. This must be a pointer to a + * #mbedtls_hmac_drbg_context structure. + * \param output The buffer to fill. + * \param out_len The length of the buffer in bytes. + * This must be at most #MBEDTLS_HMAC_DRBG_MAX_REQUEST. * - * \return 0 if successful, or - * MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED, or - * MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED + * if a call to the entropy source failed. + * \return #MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG if + * \p out_len > #MBEDTLS_HMAC_DRBG_MAX_REQUEST. */ int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len ); /** * \brief Free an HMAC_DRBG context * - * \param ctx HMAC_DRBG context to free. + * \param ctx The HMAC_DRBG context to free. */ void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx ); @@ -273,17 +356,16 @@ void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx ); #define MBEDTLS_DEPRECATED #endif /** - * \brief HMAC_DRBG update state + * \brief This function updates the state of the HMAC_DRBG context. * * \deprecated Superseded by mbedtls_hmac_drbg_update_ret() * in 2.16.0. * - * \param ctx HMAC_DRBG context - * \param additional Additional data to update state with, or NULL - * \param add_len Length of additional data, or 0 - * - * \note Additional data is optional, pass NULL and 0 as second - * third argument if no additional data is being used. + * \param ctx The HMAC_DRBG context. + * \param additional The data to update the state with. + * If this is \c NULL, there is no additional data. + * \param add_len Length of \p additional in bytes. + * Unused if \p additional is \c NULL. */ MBEDTLS_DEPRECATED void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx, @@ -293,26 +375,31 @@ MBEDTLS_DEPRECATED void mbedtls_hmac_drbg_update( #if defined(MBEDTLS_FS_IO) /** - * \brief Write a seed file + * \brief This function writes a seed file. * - * \param ctx HMAC_DRBG context - * \param path Name of the file + * \param ctx The HMAC_DRBG context. + * \param path The name of the file. * - * \return 0 if successful, 1 on file error, or - * MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED + * \return \c 0 on success. + * \return #MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR on file error. + * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED on reseed + * failure. */ int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ); /** - * \brief Read and update a seed file. Seed is added to this - * instance + * \brief This function reads and updates a seed file. The seed + * is added to this instance. * - * \param ctx HMAC_DRBG context - * \param path Name of the file + * \param ctx The HMAC_DRBG context. + * \param path The name of the file. * - * \return 0 if successful, 1 on file error, - * MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED or - * MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG + * \return \c 0 on success. + * \return #MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR on file error. + * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED on + * reseed failure. + * \return #MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG if the existing + * seed file is too large. */ int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ); #endif /* MBEDTLS_FS_IO */ @@ -320,9 +407,10 @@ int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const ch #if defined(MBEDTLS_SELF_TEST) /** - * \brief Checkup routine + * \brief The HMAC_DRBG Checkup routine. * - * \return 0 if successful, or 1 if the test failed + * \return \c 0 if successful. + * \return \c 1 if the test failed. */ int mbedtls_hmac_drbg_self_test( int verbose ); #endif diff --git a/features/mbedtls/mbed-crypto/inc/mbedtls/md_internal.h b/features/mbedtls/mbed-crypto/inc/mbedtls/md_internal.h index 267cebadcc..bb876efc5b 100644 --- a/features/mbedtls/mbed-crypto/inc/mbedtls/md_internal.h +++ b/features/mbedtls/mbed-crypto/inc/mbedtls/md_internal.h @@ -46,42 +46,17 @@ extern "C" { */ struct mbedtls_md_info_t { - /** Digest identifier */ - mbedtls_md_type_t type; - /** Name of the message digest */ const char * name; + /** Digest identifier */ + mbedtls_md_type_t type; + /** Output length of the digest function in bytes */ - int size; + unsigned char size; /** Block length of the digest function in bytes */ - int block_size; - - /** Digest initialisation function */ - int (*starts_func)( void *ctx ); - - /** Digest update function */ - int (*update_func)( void *ctx, const unsigned char *input, size_t ilen ); - - /** Digest finalisation function */ - int (*finish_func)( void *ctx, unsigned char *output ); - - /** Generic digest function */ - int (*digest_func)( const unsigned char *input, size_t ilen, - unsigned char *output ); - - /** Allocate a new context */ - void * (*ctx_alloc_func)( void ); - - /** Free the given context */ - void (*ctx_free_func)( void *ctx ); - - /** Clone state from a context */ - void (*clone_func)( void *dst, const void *src ); - - /** Internal use only */ - int (*process_func)( void *ctx, const unsigned char *input ); + unsigned char block_size; }; #if defined(MBEDTLS_MD2_C) diff --git a/features/mbedtls/mbed-crypto/inc/psa/crypto.h b/features/mbedtls/mbed-crypto/inc/psa/crypto.h index d5e713e061..7291c3e576 100644 --- a/features/mbedtls/mbed-crypto/inc/psa/crypto.h +++ b/features/mbedtls/mbed-crypto/inc/psa/crypto.h @@ -57,6 +57,22 @@ extern "C" { * algorithms, key types, policies, etc. */ #include "crypto_types.h" +/** \defgroup version API version + * @{ + */ + +/** + * The major version of this implementation of the PSA Crypto API + */ +#define PSA_CRYPTO_API_VERSION_MAJOR 1 + +/** + * The minor version of this implementation of the PSA Crypto API + */ +#define PSA_CRYPTO_API_VERSION_MINOR 0 + +/**@}*/ + /* The file "crypto_values.h" declares macros to build and analyze values * of integral types defined in "crypto_types.h". */ #include "crypto_values.h" @@ -226,7 +242,14 @@ static psa_key_usage_t psa_get_key_usage_flags( /** Declare the permitted algorithm policy for a key. * * The permitted algorithm policy of a key encodes which algorithm or - * algorithms are permitted to be used with this key. + * algorithms are permitted to be used with this key. The following + * algorithm policies are supported: + * - 0 does not allow any cryptographic operation with the key. The key + * may be used for non-cryptographic actions such as exporting (if + * permitted by the usage flags). + * - An algorithm value permits this particular algorithm. + * - An algorithm wildcard built from #PSA_ALG_ANY_HASH allows the specified + * signature scheme with any hash algorithm. * * This function overwrites any algorithm policy * previously set in \p attributes. @@ -266,6 +289,8 @@ static psa_algorithm_t psa_get_key_algorithm( * * \param[out] attributes The attribute structure to write to. * \param type The key type to write. + * If this is 0, the key type in \p attributes + * becomes unspecified. */ static void psa_set_key_type(psa_key_attributes_t *attributes, psa_key_type_t type); @@ -281,6 +306,9 @@ static void psa_set_key_type(psa_key_attributes_t *attributes, * * \param[out] attributes The attribute structure to write to. * \param bits The key size in bits. + * If this is 0, the key size in \p attributes + * becomes unspecified. Keys of size 0 are + * not supported. */ static void psa_set_key_bits(psa_key_attributes_t *attributes, size_t bits); @@ -367,15 +395,18 @@ void psa_reset_key_attributes(psa_key_attributes_t *attributes); * keys that can be opened with psa_open_key(). Such keys have a key identifier * in the vendor range, as documented in the description of #psa_key_id_t. * - * The application must eventually close the handle with psa_close_key() - * to release associated resources. If the application dies without calling - * psa_close_key(), the implementation should perform the equivalent of a - * call to psa_close_key(). + * The application must eventually close the handle with psa_close_key() or + * psa_destroy_key() to release associated resources. If the application dies + * without calling one of these functions, the implementation should perform + * the equivalent of a call to psa_close_key(). * * Some implementations permit an application to open the same key multiple - * times. Applications that rely on this behavior will not be portable to - * implementations that only permit a single key handle to be opened. See - * also :ref:\`key-handles\`. + * times. If this is successful, each call to psa_open_key() will return a + * different key handle. + * + * \note Applications that rely on opening a key multiple times will not be + * portable to implementations that only permit a single key handle to be + * opened. See also :ref:\`key-handles\`. * * \param id The persistent identifier of the key. * \param[out] handle On success, a handle to the key. @@ -422,13 +453,18 @@ psa_status_t psa_open_key(psa_key_id_t id, * Closing the key handle makes the handle invalid, and the key handle * must not be used again by the application. * - * If the key is currently in use in a multipart operation, then closing the - * last remaining handle to the key will abort the multipart operation. + * \note If the key handle was used to set up an active + * :ref:\`multipart operation \`, then closing the + * key handle can cause the multipart operation to fail. Applications should + * maintain the key handle until after the multipart operation has finished. * * \param handle The key handle to close. + * If this is \c 0, do nothing and return \c PSA_SUCCESS. * * \retval #PSA_SUCCESS + * \p handle was a valid handle or \c 0. It is now closed. * \retval #PSA_ERROR_INVALID_HANDLE + * \p handle is not a valid handle nor \c 0. * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_CORRUPTION_DETECTED * \retval #PSA_ERROR_BAD_STATE @@ -438,6 +474,144 @@ psa_status_t psa_open_key(psa_key_id_t id, */ psa_status_t psa_close_key(psa_key_handle_t handle); +/** Make a copy of a key. + * + * Copy key material from one location to another. + * + * This function is primarily useful to copy a key from one location + * to another, since it populates a key using the material from + * another key which may have a different lifetime. + * + * This function may be used to share a key with a different party, + * subject to implementation-defined restrictions on key sharing. + * + * The policy on the source key must have the usage flag + * #PSA_KEY_USAGE_COPY set. + * This flag is sufficient to permit the copy if the key has the lifetime + * #PSA_KEY_LIFETIME_VOLATILE or #PSA_KEY_LIFETIME_PERSISTENT. + * Some secure elements do not provide a way to copy a key without + * making it extractable from the secure element. If a key is located + * in such a secure element, then the key must have both usage flags + * #PSA_KEY_USAGE_COPY and #PSA_KEY_USAGE_EXPORT in order to make + * a copy of the key outside the secure element. + * + * The resulting key may only be used in a way that conforms to + * both the policy of the original key and the policy specified in + * the \p attributes parameter: + * - The usage flags on the resulting key are the bitwise-and of the + * usage flags on the source policy and the usage flags in \p attributes. + * - If both allow the same algorithm or wildcard-based + * algorithm policy, the resulting key has the same algorithm policy. + * - If either of the policies allows an algorithm and the other policy + * allows a wildcard-based algorithm policy that includes this algorithm, + * the resulting key allows the same algorithm. + * - If the policies do not allow any algorithm in common, this function + * fails with the status #PSA_ERROR_INVALID_ARGUMENT. + * + * The effect of this function on implementation-defined attributes is + * implementation-defined. + * + * \param source_handle The key to copy. It must be a valid key handle. + * \param[in] attributes The attributes for the new key. + * They are used as follows: + * - The key type and size may be 0. If either is + * nonzero, it must match the corresponding + * attribute of the source key. + * - The key location (the lifetime and, for + * persistent keys, the key identifier) is + * used directly. + * - The policy constraints (usage flags and + * algorithm policy) are combined from + * the source key and \p attributes so that + * both sets of restrictions apply, as + * described in the documentation of this function. + * \param[out] target_handle On success, a handle to the newly created key. + * \c 0 on failure. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INVALID_HANDLE + * \p source_handle is invalid. + * \retval #PSA_ERROR_ALREADY_EXISTS + * This is an attempt to create a persistent key, and there is + * already a persistent key with the given identifier. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The lifetime or identifier in \p attributes are invalid. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The policy constraints on the source and specified in + * \p attributes are incompatible. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p attributes specifies a key type or key size + * which does not match the attributes of the source key. + * \retval #PSA_ERROR_NOT_PERMITTED + * The source key does not have the #PSA_KEY_USAGE_COPY usage flag. + * \retval #PSA_ERROR_NOT_PERMITTED + * The source key is not exportable and its lifetime does not + * allow copying it to the target's lifetime. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_copy_key(psa_key_handle_t source_handle, + const psa_key_attributes_t *attributes, + psa_key_handle_t *target_handle); + + +/** + * \brief Destroy a key. + * + * This function destroys a key from both volatile + * memory and, if applicable, non-volatile storage. Implementations shall + * make a best effort to ensure that that the key material cannot be recovered. + * + * This function also erases any metadata such as policies and frees + * resources associated with the key. To free all resources associated with + * the key, all handles to the key must be closed or destroyed. + * + * Destroying the key makes the handle invalid, and the key handle + * must not be used again by the application. Using other open handles to the + * destroyed key in a cryptographic operation will result in an error. + * + * If a key is currently in use in a multipart operation, then destroying the + * key will cause the multipart operation to fail. + * + * \param handle Handle to the key to erase. + * If this is \c 0, do nothing and return \c PSA_SUCCESS. + * + * \retval #PSA_SUCCESS + * \p handle was a valid handle and the key material that it + * referred to has been erased. + * Alternatively, \p handle is \c 0. + * \retval #PSA_ERROR_NOT_PERMITTED + * The key cannot be erased because it is + * read-only, either due to a policy or due to physical restrictions. + * \retval #PSA_ERROR_INVALID_HANDLE + * \p handle is not a valid handle nor \c 0. + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * There was an failure in communication with the cryptoprocessor. + * The key material may still be present in the cryptoprocessor. + * \retval #PSA_ERROR_STORAGE_FAILURE + * The storage is corrupted. Implementations shall make a best effort + * to erase key material even in this stage, however applications + * should be aware that it may be impossible to guarantee that the + * key material is not recoverable in such cases. + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * An unexpected condition which is not a storage corruption or + * a communication failure occurred. The cryptoprocessor may have + * been compromised. + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_destroy_key(psa_key_handle_t handle); + /**@}*/ /** \defgroup import_export Key import and export @@ -452,6 +626,13 @@ psa_status_t psa_close_key(psa_key_handle_t handle); * and to the documentation of psa_export_key() for the format for * other key types. * + * The key data determines the key size. The attributes may optionally + * specify a key size; in this case it must match the size determined + * from the key data. A key size of 0 in \p attributes indicates that + * the key size is solely determined by the key data. + * + * Implementations must reject an attempt to import a key of size 0. + * * This specification supports a single format for each key type. * Implementations may support other formats as long as the standard * format is supported. Implementations that support other formats @@ -459,7 +640,6 @@ psa_status_t psa_close_key(psa_key_handle_t handle); * minimize the risk that an invalid input is accidentally interpreted * according to a different format. * - * \param[in] attributes The attributes for the new key. * The key size is always determined from the * \p data buffer. @@ -503,8 +683,6 @@ psa_status_t psa_close_key(psa_key_handle_t handle); * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_CORRUPTION_DETECTED * \retval #PSA_ERROR_BAD_STATE - * \p operation is either not initialized or is in use - * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize * results in this error code. @@ -514,47 +692,7 @@ psa_status_t psa_import_key(const psa_key_attributes_t *attributes, size_t data_length, psa_key_handle_t *handle); -/** - * \brief Destroy a key. - * - * This function destroys a key from both volatile - * memory and, if applicable, non-volatile storage. Implementations shall - * make a best effort to ensure that that the key material cannot be recovered. - * - * This function also erases any metadata such as policies and frees all - * resources associated with the key. - * - * Destroying a key will invalidate all existing handles to the key. - * - * If the key is currently in use in a multipart operation, then destroying the - * key will abort the multipart operation. - * - * \param handle Handle to the key to erase. - * - * \retval #PSA_SUCCESS - * The key material has been erased. - * \retval #PSA_ERROR_NOT_PERMITTED - * The key cannot be erased because it is - * read-only, either due to a policy or due to physical restrictions. - * \retval #PSA_ERROR_INVALID_HANDLE - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * There was an failure in communication with the cryptoprocessor. - * The key material may still be present in the cryptoprocessor. - * \retval #PSA_ERROR_STORAGE_FAILURE - * The storage is corrupted. Implementations shall make a best effort - * to erase key material even in this stage, however applications - * should be aware that it may be impossible to guarantee that the - * key material is not recoverable in such cases. - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * An unexpected condition which is not a storage corruption or - * a communication failure occurred. The cryptoprocessor may have - * been compromised. - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_destroy_key(psa_key_handle_t handle); + /** * \brief Export a key in binary format. @@ -714,93 +852,7 @@ psa_status_t psa_export_public_key(psa_key_handle_t handle, size_t data_size, size_t *data_length); -/** Make a copy of a key. - * - * Copy key material from one location to another. - * - * This function is primarily useful to copy a key from one location - * to another, since it populates a key using the material from - * another key which may have a different lifetime. - * - * This function may be used to share a key with a different party, - * subject to implementation-defined restrictions on key sharing. - * - * The policy on the source key must have the usage flag - * #PSA_KEY_USAGE_COPY set. - * This flag is sufficient to permit the copy if the key has the lifetime - * #PSA_KEY_LIFETIME_VOLATILE or #PSA_KEY_LIFETIME_PERSISTENT. - * Some secure elements do not provide a way to copy a key without - * making it extractable from the secure element. If a key is located - * in such a secure element, then the key must have both usage flags - * #PSA_KEY_USAGE_COPY and #PSA_KEY_USAGE_EXPORT in order to make - * a copy of the key outside the secure element. - * - * The resulting key may only be used in a way that conforms to - * both the policy of the original key and the policy specified in - * the \p attributes parameter: - * - The usage flags on the resulting key are the bitwise-and of the - * usage flags on the source policy and the usage flags in \p attributes. - * - If both allow the same algorithm or wildcard-based - * algorithm policy, the resulting key has the same algorithm policy. - * - If either of the policies allows an algorithm and the other policy - * allows a wildcard-based algorithm policy that includes this algorithm, - * the resulting key allows the same algorithm. - * - If the policies do not allow any algorithm in common, this function - * fails with the status #PSA_ERROR_INVALID_ARGUMENT. - * - * The effect of this function on implementation-defined attributes is - * implementation-defined. - * - * \param source_handle The key to copy. It must be a valid key handle. - * \param[in] attributes The attributes for the new key. - * They are used as follows: - * - The key type and size may be 0. If either is - * nonzero, it must match the corresponding - * attribute of the source key. - * - The key location (the lifetime and, for - * persistent keys, the key identifier) is - * used directly. - * - The policy constraints (usage flags and - * algorithm policy) are combined from - * the source key and \p attributes so that - * both sets of restrictions apply, as - * described in the documentation of this function. - * \param[out] target_handle On success, a handle to the newly created key. - * \c 0 on failure. - * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_INVALID_HANDLE - * \p source_handle is invalid. - * \retval #PSA_ERROR_ALREADY_EXISTS - * This is an attempt to create a persistent key, and there is - * already a persistent key with the given identifier. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The lifetime or identifier in \p attributes are invalid. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The policy constraints on the source and specified in - * \p attributes are incompatible. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p attributes specifies a key type or key size - * which does not match the attributes of the source key. - * \retval #PSA_ERROR_NOT_PERMITTED - * The source key does not have the #PSA_KEY_USAGE_COPY usage flag. - * \retval #PSA_ERROR_NOT_PERMITTED - * The source key is not exportable and its lifetime does not - * allow copying it to the target's lifetime. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_copy_key(psa_key_handle_t source_handle, - const psa_key_attributes_t *attributes, - psa_key_handle_t *target_handle); + /**@}*/ @@ -935,7 +987,7 @@ static psa_hash_operation_t psa_hash_operation_init(void); * -# Allocate an operation object which will be passed to all the functions * listed here. * -# Initialize the operation object with one of the methods described in the - * documentation for #psa_hash_operation_t, e.g. PSA_HASH_OPERATION_INIT. + * documentation for #psa_hash_operation_t, e.g. #PSA_HASH_OPERATION_INIT. * -# Call psa_hash_setup() to specify the algorithm. * -# Call psa_hash_update() zero, one or more times, passing a fragment * of the message each time. The hash that is calculated is the hash @@ -943,14 +995,16 @@ static psa_hash_operation_t psa_hash_operation_init(void); * -# To calculate the hash, call psa_hash_finish(). * To compare the hash with an expected value, call psa_hash_verify(). * - * The application may call psa_hash_abort() at any time after the operation + * If an error occurs at any step after a call to psa_hash_setup(), the + * operation will need to be reset by a call to psa_hash_abort(). The + * application may call psa_hash_abort() at any time after the operation * has been initialized. * * After a successful call to psa_hash_setup(), the application must * eventually terminate the operation. The following events terminate an * operation: - * - A failed call to psa_hash_update(). - * - A call to psa_hash_finish(), psa_hash_verify() or psa_hash_abort(). + * - A successful call to psa_hash_finish() or psa_hash_verify(). + * - A call to psa_hash_abort(). * * \param[in,out] operation The operation object to set up. It must have * been initialized as per the documentation for @@ -965,15 +1019,12 @@ static psa_hash_operation_t psa_hash_operation_init(void); * \retval #PSA_ERROR_INVALID_ARGUMENT * \p alg is not a hash algorithm. * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (already set up and not - * subsequently completed). + * The operation state is not valid (it must be inactive). * \retval #PSA_ERROR_INSUFFICIENT_MEMORY * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_CORRUPTION_DETECTED * \retval #PSA_ERROR_BAD_STATE - * \p operation is either not initialized or is in use - * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize * results in this error code. @@ -985,7 +1036,8 @@ psa_status_t psa_hash_setup(psa_hash_operation_t *operation, * * The application must call psa_hash_setup() before calling this function. * - * If this function returns an error status, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_hash_abort(). * * \param[in,out] operation Active hash operation. * \param[in] input Buffer containing the message fragment to hash. @@ -994,14 +1046,12 @@ psa_status_t psa_hash_setup(psa_hash_operation_t *operation, * \retval #PSA_SUCCESS * Success. * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (not set up, or already completed). + * The operation state is not valid (it muct be active). * \retval #PSA_ERROR_INSUFFICIENT_MEMORY * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_CORRUPTION_DETECTED * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid. - * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize * results in this error code. @@ -1016,7 +1066,9 @@ psa_status_t psa_hash_update(psa_hash_operation_t *operation, * This function calculates the hash of the message formed by concatenating * the inputs passed to preceding calls to psa_hash_update(). * - * When this function returns, the operation becomes inactive. + * When this function returns successfuly, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_hash_abort(). * * \warning Applications should not call this function if they expect * a specific value for the hash. Call psa_hash_verify() instead. @@ -1037,7 +1089,7 @@ psa_status_t psa_hash_update(psa_hash_operation_t *operation, * \retval #PSA_SUCCESS * Success. * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (not set up, or already completed). + * The operation state is not valid (it must be active). * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p hash buffer is too small. You can determine a * sufficient buffer size by calling #PSA_HASH_SIZE(\c alg) @@ -1047,8 +1099,6 @@ psa_status_t psa_hash_update(psa_hash_operation_t *operation, * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_CORRUPTION_DETECTED * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid. - * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize * results in this error code. @@ -1067,7 +1117,9 @@ psa_status_t psa_hash_finish(psa_hash_operation_t *operation, * compares the calculated hash with the expected hash passed as a * parameter to this function. * - * When this function returns, the operation becomes inactive. + * When this function returns successfuly, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_hash_abort(). * * \note Implementations shall make the best effort to ensure that the * comparison between the actual hash and the expected hash is performed @@ -1083,14 +1135,12 @@ psa_status_t psa_hash_finish(psa_hash_operation_t *operation, * The hash of the message was calculated successfully, but it * differs from the expected hash. * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (not set up, or already completed). + * The operation state is not valid (it must be active). * \retval #PSA_ERROR_INSUFFICIENT_MEMORY * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_CORRUPTION_DETECTED * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid. - * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize * results in this error code. @@ -1107,11 +1157,7 @@ psa_status_t psa_hash_verify(psa_hash_operation_t *operation, * psa_hash_setup() again. * * You may call this function any time after the operation object has - * been initialized by any of the following methods: - * - A call to psa_hash_setup(), whether it succeeds or not. - * - Initializing the \c struct to all-bits-zero. - * - Initializing the \c struct to logical zeros, e.g. - * `psa_hash_operation_t operation = {0}`. + * been initialized by one of the methods described in #psa_hash_operation_t. * * In particular, calling psa_hash_abort() after the operation has been * terminated by a call to psa_hash_abort(), psa_hash_finish() or @@ -1120,14 +1166,10 @@ psa_status_t psa_hash_verify(psa_hash_operation_t *operation, * \param[in,out] operation Initialized hash operation. * * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_BAD_STATE - * \p operation is not an active hash operation. * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_CORRUPTION_DETECTED * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid. - * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize * results in this error code. @@ -1151,18 +1193,14 @@ psa_status_t psa_hash_abort(psa_hash_operation_t *operation); * * \retval #PSA_SUCCESS * \retval #PSA_ERROR_BAD_STATE - * \p source_operation is not an active hash operation. + * The \p source_operation state is not valid (it must be active). * \retval #PSA_ERROR_BAD_STATE - * \p target_operation is active. + * The \p target_operation state is not valid (it must be inactive). * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_CORRUPTION_DETECTED * \retval #PSA_ERROR_INSUFFICIENT_MEMORY * \retval #PSA_ERROR_BAD_STATE - * The operation state is either not initialized or has already been setup. - * \retval #PSA_ERROR_BAD_STATE - * The operation state is either not initialized or has already been setup. - * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize * results in this error code. @@ -1321,7 +1359,7 @@ static psa_mac_operation_t psa_mac_operation_init(void); * -# Allocate an operation object which will be passed to all the functions * listed here. * -# Initialize the operation object with one of the methods described in the - * documentation for #psa_mac_operation_t, e.g. PSA_MAC_OPERATION_INIT. + * documentation for #psa_mac_operation_t, e.g. #PSA_MAC_OPERATION_INIT. * -# Call psa_mac_sign_setup() to specify the algorithm and key. * -# Call psa_mac_update() zero, one or more times, passing a fragment * of the message each time. The MAC that is calculated is the MAC @@ -1329,13 +1367,15 @@ static psa_mac_operation_t psa_mac_operation_init(void); * -# At the end of the message, call psa_mac_sign_finish() to finish * calculating the MAC value and retrieve it. * - * The application may call psa_mac_abort() at any time after the operation + * If an error occurs at any step after a call to psa_mac_sign_setup(), the + * operation will need to be reset by a call to psa_mac_abort(). The + * application may call psa_mac_abort() at any time after the operation * has been initialized. * * After a successful call to psa_mac_sign_setup(), the application must * eventually terminate the operation through one of the following methods: - * - A failed call to psa_mac_update(). - * - A call to psa_mac_sign_finish() or psa_mac_abort(). + * - A successful call to psa_mac_sign_finish(). + * - A call to psa_mac_abort(). * * \param[in,out] operation The operation object to set up. It must have * been initialized as per the documentation for @@ -1361,8 +1401,7 @@ static psa_mac_operation_t psa_mac_operation_init(void); * \retval #PSA_ERROR_STORAGE_FAILURE * The key could not be retrieved from storage. * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (already set up and not - * subsequently completed). + * The operation state is not valid (it must be inactive). * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -1381,7 +1420,7 @@ psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation, * -# Allocate an operation object which will be passed to all the functions * listed here. * -# Initialize the operation object with one of the methods described in the - * documentation for #psa_mac_operation_t, e.g. PSA_MAC_OPERATION_INIT. + * documentation for #psa_mac_operation_t, e.g. #PSA_MAC_OPERATION_INIT. * -# Call psa_mac_verify_setup() to specify the algorithm and key. * -# Call psa_mac_update() zero, one or more times, passing a fragment * of the message each time. The MAC that is calculated is the MAC @@ -1390,13 +1429,15 @@ psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation, * calculating the actual MAC of the message and verify it against * the expected value. * - * The application may call psa_mac_abort() at any time after the operation + * If an error occurs at any step after a call to psa_mac_verify_setup(), the + * operation will need to be reset by a call to psa_mac_abort(). The + * application may call psa_mac_abort() at any time after the operation * has been initialized. * * After a successful call to psa_mac_verify_setup(), the application must * eventually terminate the operation through one of the following methods: - * - A failed call to psa_mac_update(). - * - A call to psa_mac_verify_finish() or psa_mac_abort(). + * - A successful call to psa_mac_verify_finish(). + * - A call to psa_mac_abort(). * * \param[in,out] operation The operation object to set up. It must have * been initialized as per the documentation for @@ -1422,8 +1463,7 @@ psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation, * \retval #PSA_ERROR_STORAGE_FAILURE * The key could not be retrieved from storage * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (already set up and not - * subsequently completed). + * The operation state is not valid (it must be inactive). * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -1438,7 +1478,8 @@ psa_status_t psa_mac_verify_setup(psa_mac_operation_t *operation, * The application must call psa_mac_sign_setup() or psa_mac_verify_setup() * before calling this function. * - * If this function returns an error status, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_mac_abort(). * * \param[in,out] operation Active MAC operation. * \param[in] input Buffer containing the message fragment to add to @@ -1448,7 +1489,7 @@ psa_status_t psa_mac_verify_setup(psa_mac_operation_t *operation, * \retval #PSA_SUCCESS * Success. * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (not set up, or already completed). + * The operation state is not valid (it must be active). * \retval #PSA_ERROR_INSUFFICIENT_MEMORY * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE @@ -1469,7 +1510,9 @@ psa_status_t psa_mac_update(psa_mac_operation_t *operation, * This function calculates the MAC of the message formed by concatenating * the inputs passed to preceding calls to psa_mac_update(). * - * When this function returns, the operation becomes inactive. + * When this function returns successfuly, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_mac_abort(). * * \warning Applications should not call this function if they expect * a specific value for the MAC. Call psa_mac_verify_finish() instead. @@ -1492,7 +1535,8 @@ psa_status_t psa_mac_update(psa_mac_operation_t *operation, * \retval #PSA_SUCCESS * Success. * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (not set up, or already completed). + * The operation state is not valid (it must be an active mac sign + * operation). * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p mac buffer is too small. You can determine a * sufficient buffer size by calling PSA_MAC_FINAL_SIZE(). @@ -1520,7 +1564,9 @@ psa_status_t psa_mac_sign_finish(psa_mac_operation_t *operation, * compares the calculated MAC with the expected MAC passed as a * parameter to this function. * - * When this function returns, the operation becomes inactive. + * When this function returns successfuly, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_mac_abort(). * * \note Implementations shall make the best effort to ensure that the * comparison between the actual MAC and the expected MAC is performed @@ -1536,7 +1582,8 @@ psa_status_t psa_mac_sign_finish(psa_mac_operation_t *operation, * The MAC of the message was calculated successfully, but it * differs from the expected MAC. * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (not set up, or already completed). + * The operation state is not valid (it must be an active mac verify + * operation). * \retval #PSA_ERROR_INSUFFICIENT_MEMORY * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE @@ -1559,12 +1606,7 @@ psa_status_t psa_mac_verify_finish(psa_mac_operation_t *operation, * psa_mac_sign_setup() or psa_mac_verify_setup() again. * * You may call this function any time after the operation object has - * been initialized by any of the following methods: - * - A call to psa_mac_sign_setup() or psa_mac_verify_setup(), whether - * it succeeds or not. - * - Initializing the \c struct to all-bits-zero. - * - Initializing the \c struct to logical zeros, e.g. - * `psa_mac_operation_t operation = {0}`. + * been initialized by one of the methods described in #psa_mac_operation_t. * * In particular, calling psa_mac_abort() after the operation has been * terminated by a call to psa_mac_abort(), psa_mac_sign_finish() or @@ -1573,8 +1615,6 @@ psa_status_t psa_mac_verify_finish(psa_mac_operation_t *operation, * \param[in,out] operation Initialized MAC operation. * * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_BAD_STATE - * \p operation is not an active MAC operation. * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_CORRUPTION_DETECTED @@ -1594,7 +1634,8 @@ psa_status_t psa_mac_abort(psa_mac_operation_t *operation); /** Encrypt a message using a symmetric cipher. * * This function encrypts a message with a random IV (initialization - * vector). + * vector). Use the multipart operation interface with a + * #psa_cipher_operation_t object to provide other forms of IV. * * \param handle Handle to the key to use for the operation. * It must remain valid until the operation @@ -1738,7 +1779,7 @@ static psa_cipher_operation_t psa_cipher_operation_init(void); * listed here. * -# Initialize the operation object with one of the methods described in the * documentation for #psa_cipher_operation_t, e.g. - * PSA_CIPHER_OPERATION_INIT. + * #PSA_CIPHER_OPERATION_INIT. * -# Call psa_cipher_encrypt_setup() to specify the algorithm and key. * -# Call either psa_cipher_generate_iv() or psa_cipher_set_iv() to * generate or set the IV (initialization vector). You should use @@ -1748,14 +1789,16 @@ static psa_cipher_operation_t psa_cipher_operation_init(void); * of the message each time. * -# Call psa_cipher_finish(). * - * The application may call psa_cipher_abort() at any time after the operation + * If an error occurs at any step after a call to psa_cipher_encrypt_setup(), + * the operation will need to be reset by a call to psa_cipher_abort(). The + * application may call psa_cipher_abort() at any time after the operation * has been initialized. * * After a successful call to psa_cipher_encrypt_setup(), the application must * eventually terminate the operation. The following events terminate an * operation: - * - A failed call to any of the \c psa_cipher_xxx functions. - * - A call to psa_cipher_finish() or psa_cipher_abort(). + * - A successful call to psa_cipher_finish(). + * - A call to psa_cipher_abort(). * * \param[in,out] operation The operation object to set up. It must have * been initialized as per the documentation for @@ -1781,8 +1824,7 @@ static psa_cipher_operation_t psa_cipher_operation_init(void); * \retval #PSA_ERROR_CORRUPTION_DETECTED * \retval #PSA_ERROR_STORAGE_FAILURE * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (already set up and not - * subsequently completed). + * The operation state is not valid (it must be inactive). * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -1800,7 +1842,7 @@ psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation, * listed here. * -# Initialize the operation object with one of the methods described in the * documentation for #psa_cipher_operation_t, e.g. - * PSA_CIPHER_OPERATION_INIT. + * #PSA_CIPHER_OPERATION_INIT. * -# Call psa_cipher_decrypt_setup() to specify the algorithm and key. * -# Call psa_cipher_set_iv() with the IV (initialization vector) for the * decryption. If the IV is prepended to the ciphertext, you can call @@ -1810,14 +1852,16 @@ psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation, * of the message each time. * -# Call psa_cipher_finish(). * - * The application may call psa_cipher_abort() at any time after the operation + * If an error occurs at any step after a call to psa_cipher_decrypt_setup(), + * the operation will need to be reset by a call to psa_cipher_abort(). The + * application may call psa_cipher_abort() at any time after the operation * has been initialized. * * After a successful call to psa_cipher_decrypt_setup(), the application must * eventually terminate the operation. The following events terminate an * operation: - * - A failed call to any of the \c psa_cipher_xxx functions. - * - A call to psa_cipher_finish() or psa_cipher_abort(). + * - A successful call to psa_cipher_finish(). + * - A call to psa_cipher_abort(). * * \param[in,out] operation The operation object to set up. It must have * been initialized as per the documentation for @@ -1843,8 +1887,7 @@ psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation, * \retval #PSA_ERROR_CORRUPTION_DETECTED * \retval #PSA_ERROR_STORAGE_FAILURE * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (already set up and not - * subsequently completed). + * The operation state is not valid (it must be inactive). * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -1863,7 +1906,8 @@ psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation, * The application must call psa_cipher_encrypt_setup() before * calling this function. * - * If this function returns an error status, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_cipher_abort(). * * \param[in,out] operation Active cipher operation. * \param[out] iv Buffer where the generated IV is to be written. @@ -1874,7 +1918,7 @@ psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation, * \retval #PSA_SUCCESS * Success. * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (not set up, or IV already set). + * The operation state is not valid (it must be active, with no IV set). * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p iv buffer is too small. * \retval #PSA_ERROR_INSUFFICIENT_MEMORY @@ -1900,7 +1944,8 @@ psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation, * The application must call psa_cipher_encrypt_setup() before * calling this function. * - * If this function returns an error status, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_cipher_abort(). * * \note When encrypting, applications should use psa_cipher_generate_iv() * instead of this function, unless implementing a protocol that requires @@ -1913,7 +1958,8 @@ psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation, * \retval #PSA_SUCCESS * Success. * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (not set up, or IV already set). + * The operation state is not valid (it must be an active cipher + * encrypt operation, with no IV set). * \retval #PSA_ERROR_INVALID_ARGUMENT * The size of \p iv is not acceptable for the chosen algorithm, * or the chosen algorithm does not use an IV. @@ -1940,7 +1986,8 @@ psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation, * 2. If the algorithm requires an IV, call psa_cipher_generate_iv() * (recommended when encrypting) or psa_cipher_set_iv(). * - * If this function returns an error status, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_cipher_abort(). * * \param[in,out] operation Active cipher operation. * \param[in] input Buffer containing the message fragment to @@ -1954,8 +2001,8 @@ psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation, * \retval #PSA_SUCCESS * Success. * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (not set up, IV required but - * not set, or already completed). + * The operation state is not valid (it must be active, with an IV set + * if required for the algorithm). * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p output buffer is too small. * \retval #PSA_ERROR_INSUFFICIENT_MEMORY @@ -1986,7 +2033,9 @@ psa_status_t psa_cipher_update(psa_cipher_operation_t *operation, * formed by concatenating the inputs passed to preceding calls to * psa_cipher_update(). * - * When this function returns, the operation becomes inactive. + * When this function returns successfuly, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_cipher_abort(). * * \param[in,out] operation Active cipher operation. * \param[out] output Buffer where the output is to be written. @@ -1996,9 +2045,17 @@ psa_status_t psa_cipher_update(psa_cipher_operation_t *operation, * * \retval #PSA_SUCCESS * Success. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The total input size passed to this operation is not valid for + * this particular algorithm. For example, the algorithm is a based + * on block cipher and requires a whole number of blocks, but the + * total input size is not a multiple of the block size. + * \retval #PSA_ERROR_INVALID_PADDING + * This is a decryption operation for an algorithm that includes + * padding, and the ciphertext does not contain valid padding. * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (not set up, IV required but - * not set, or already completed). + * The operation state is not valid (it must be active, with an IV set + * if required for the algorithm). * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p output buffer is too small. * \retval #PSA_ERROR_INSUFFICIENT_MEMORY @@ -2024,12 +2081,7 @@ psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation, * psa_cipher_encrypt_setup() or psa_cipher_decrypt_setup() again. * * You may call this function any time after the operation object has - * been initialized by any of the following methods: - * - A call to psa_cipher_encrypt_setup() or psa_cipher_decrypt_setup(), - * whether it succeeds or not. - * - Initializing the \c struct to all-bits-zero. - * - Initializing the \c struct to logical zeros, e.g. - * `psa_cipher_operation_t operation = {0}`. + * been initialized as described in #psa_cipher_operation_t. * * In particular, calling psa_cipher_abort() after the operation has been * terminated by a call to psa_cipher_abort() or psa_cipher_finish() @@ -2038,8 +2090,6 @@ psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation, * \param[in,out] operation Initialized cipher operation. * * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_BAD_STATE - * \p operation is not an active cipher operation. * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_CORRUPTION_DETECTED @@ -2230,7 +2280,7 @@ static psa_aead_operation_t psa_aead_operation_init(void); * listed here. * -# Initialize the operation object with one of the methods described in the * documentation for #psa_aead_operation_t, e.g. - * PSA_AEAD_OPERATION_INIT. + * #PSA_AEAD_OPERATION_INIT. * -# Call psa_aead_encrypt_setup() to specify the algorithm and key. * -# If needed, call psa_aead_set_lengths() to specify the length of the * inputs to the subsequent calls to psa_aead_update_ad() and @@ -2246,14 +2296,16 @@ static psa_aead_operation_t psa_aead_operation_init(void); * of the message to encrypt each time. * -# Call psa_aead_finish(). * - * The application may call psa_aead_abort() at any time after the operation + * If an error occurs at any step after a call to psa_aead_encrypt_setup(), + * the operation will need to be reset by a call to psa_aead_abort(). The + * application may call psa_aead_abort() at any time after the operation * has been initialized. * * After a successful call to psa_aead_encrypt_setup(), the application must * eventually terminate the operation. The following events terminate an * operation: - * - A failed call to any of the \c psa_aead_xxx functions. - * - A call to psa_aead_finish(), psa_aead_verify() or psa_aead_abort(). + * - A successful call to psa_aead_finish(). + * - A call to psa_aead_abort(). * * \param[in,out] operation The operation object to set up. It must have * been initialized as per the documentation for @@ -2267,7 +2319,9 @@ static psa_aead_operation_t psa_aead_operation_init(void); * * \retval #PSA_SUCCESS * Success. - * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be inactive). + * \retval #PSA_ERROR_INVALID_HANDLE * \retval #PSA_ERROR_NOT_PERMITTED * \retval #PSA_ERROR_INVALID_ARGUMENT * \p handle is not compatible with \p alg. @@ -2295,7 +2349,7 @@ psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation, * listed here. * -# Initialize the operation object with one of the methods described in the * documentation for #psa_aead_operation_t, e.g. - * PSA_AEAD_OPERATION_INIT. + * #PSA_AEAD_OPERATION_INIT. * -# Call psa_aead_decrypt_setup() to specify the algorithm and key. * -# If needed, call psa_aead_set_lengths() to specify the length of the * inputs to the subsequent calls to psa_aead_update_ad() and @@ -2308,14 +2362,16 @@ psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation, * of the ciphertext to decrypt each time. * -# Call psa_aead_verify(). * - * The application may call psa_aead_abort() at any time after the operation + * If an error occurs at any step after a call to psa_aead_decrypt_setup(), + * the operation will need to be reset by a call to psa_aead_abort(). The + * application may call psa_aead_abort() at any time after the operation * has been initialized. * * After a successful call to psa_aead_decrypt_setup(), the application must * eventually terminate the operation. The following events terminate an * operation: - * - A failed call to any of the \c psa_aead_xxx functions. - * - A call to psa_aead_finish(), psa_aead_verify() or psa_aead_abort(). + * - A successful call to psa_aead_verify(). + * - A call to psa_aead_abort(). * * \param[in,out] operation The operation object to set up. It must have * been initialized as per the documentation for @@ -2329,7 +2385,9 @@ psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation, * * \retval #PSA_SUCCESS * Success. - * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be inactive). + * \retval #PSA_ERROR_INVALID_HANDLE * \retval #PSA_ERROR_NOT_PERMITTED * \retval #PSA_ERROR_INVALID_ARGUMENT * \p handle is not compatible with \p alg. @@ -2358,7 +2416,8 @@ psa_status_t psa_aead_decrypt_setup(psa_aead_operation_t *operation, * The application must call psa_aead_encrypt_setup() before * calling this function. * - * If this function returns an error status, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_aead_abort(). * * \param[in,out] operation Active AEAD operation. * \param[out] nonce Buffer where the generated nonce is to be @@ -2370,7 +2429,8 @@ psa_status_t psa_aead_decrypt_setup(psa_aead_operation_t *operation, * \retval #PSA_SUCCESS * Success. * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (not set up, or nonce already set). + * The operation state is not valid (it must be an active aead encrypt + operation, with no nonce set). * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p nonce buffer is too small. * \retval #PSA_ERROR_INSUFFICIENT_MEMORY @@ -2393,10 +2453,11 @@ psa_status_t psa_aead_generate_nonce(psa_aead_operation_t *operation, * This function sets the nonce for the authenticated * encryption or decryption operation. * - * The application must call psa_aead_encrypt_setup() before - * calling this function. + * The application must call psa_aead_encrypt_setup() or + * psa_aead_decrypt_setup() before calling this function. * - * If this function returns an error status, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_aead_abort(). * * \note When encrypting, applications should use psa_aead_generate_nonce() * instead of this function, unless implementing a protocol that requires @@ -2409,7 +2470,8 @@ psa_status_t psa_aead_generate_nonce(psa_aead_operation_t *operation, * \retval #PSA_SUCCESS * Success. * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (not set up, or nonce already set). + * The operation state is not valid (it must be active, with no nonce + * set). * \retval #PSA_ERROR_INVALID_ARGUMENT * The size of \p nonce is not acceptable for the chosen algorithm. * \retval #PSA_ERROR_INSUFFICIENT_MEMORY @@ -2442,6 +2504,9 @@ psa_status_t psa_aead_set_nonce(psa_aead_operation_t *operation, * this function is not required. * - For vendor-defined algorithm, refer to the vendor documentation. * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_aead_abort(). + * * \param[in,out] operation Active AEAD operation. * \param ad_length Size of the non-encrypted additional * authenticated data in bytes. @@ -2450,8 +2515,9 @@ psa_status_t psa_aead_set_nonce(psa_aead_operation_t *operation, * \retval #PSA_SUCCESS * Success. * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (not set up, already completed, - * or psa_aead_update_ad() or psa_aead_update() already called). + * The operation state is not valid (it must be active, and + * psa_aead_update_ad() and psa_aead_update() must not have been + * called yet). * \retval #PSA_ERROR_INVALID_ARGUMENT * At least one of the lengths is not acceptable for the chosen * algorithm. @@ -2480,7 +2546,8 @@ psa_status_t psa_aead_set_lengths(psa_aead_operation_t *operation, * 1. Call either psa_aead_encrypt_setup() or psa_aead_decrypt_setup(). * 2. Set the nonce with psa_aead_generate_nonce() or psa_aead_set_nonce(). * - * If this function returns an error status, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_aead_abort(). * * \warning When decrypting, until psa_aead_verify() has returned #PSA_SUCCESS, * there is no guarantee that the input is valid. Therefore, until @@ -2496,8 +2563,9 @@ psa_status_t psa_aead_set_lengths(psa_aead_operation_t *operation, * \retval #PSA_SUCCESS * Success. * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (not set up, nonce not set, - * psa_aead_update() already called, or operation already completed). + * The operation state is not valid (it must be active, have a nonce + * set, have lengths set if required by the algorithm, and + * psa_aead_update() must not have been called yet). * \retval #PSA_ERROR_INVALID_ARGUMENT * The total input length overflows the additional data length that * was previously specified with psa_aead_set_lengths(). @@ -2524,7 +2592,8 @@ psa_status_t psa_aead_update_ad(psa_aead_operation_t *operation, * 2. Set the nonce with psa_aead_generate_nonce() or psa_aead_set_nonce(). * 3. Call psa_aead_update_ad() to pass all the additional data. * - * If this function returns an error status, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_aead_abort(). * * \warning When decrypting, until psa_aead_verify() has returned #PSA_SUCCESS, * there is no guarantee that the input is valid. Therefore, until @@ -2564,8 +2633,8 @@ psa_status_t psa_aead_update_ad(psa_aead_operation_t *operation, * \retval #PSA_SUCCESS * Success. * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (not set up, nonce not set - * or already completed). + * The operation state is not valid (it must be active, have a nonce + * set, and have lengths set if required by the algorithm). * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p output buffer is too small. * You can determine a sufficient buffer size by calling @@ -2611,7 +2680,9 @@ psa_status_t psa_aead_update(psa_aead_operation_t *operation, * #PSA_AEAD_TAG_LENGTH(\c alg) where \c alg is the AEAD algorithm * that the operation performs. * - * When this function returns, the operation becomes inactive. + * When this function returns successfuly, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_aead_abort(). * * \param[in,out] operation Active AEAD operation. * \param[out] ciphertext Buffer where the last part of the ciphertext @@ -2635,8 +2706,8 @@ psa_status_t psa_aead_update(psa_aead_operation_t *operation, * \retval #PSA_SUCCESS * Success. * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (not set up, nonce not set, - * decryption, or already completed). + * The operation state is not valid (it must be an active encryption + * operation with a nonce set). * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p ciphertext or \p tag buffer is too small. * You can determine a sufficient buffer size for \p ciphertext by @@ -2674,12 +2745,26 @@ psa_status_t psa_aead_finish(psa_aead_operation_t *operation, * * The operation must have been set up with psa_aead_decrypt_setup(). * - * This function finishes the authentication of the additional data - * formed by concatenating the inputs passed to preceding calls to - * psa_aead_update_ad() with the ciphertext formed by concatenating the - * inputs passed to preceding calls to psa_aead_update(). + * This function finishes the authenticated decryption of the message + * components: * - * When this function returns, the operation becomes inactive. + * - The additional data consisting of the concatenation of the inputs + * passed to preceding calls to psa_aead_update_ad(). + * - The ciphertext consisting of the concatenation of the inputs passed to + * preceding calls to psa_aead_update(). + * - The tag passed to this function call. + * + * If the authentication tag is correct, this function outputs any remaining + * plaintext and reports success. If the authentication tag is not correct, + * this function returns #PSA_ERROR_INVALID_SIGNATURE. + * + * When this function returns successfuly, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_aead_abort(). + * + * \note Implementations shall make the best effort to ensure that the + * comparison between the actual tag and the expected tag is performed + * in constant time. * * \param[in,out] operation Active AEAD operation. * \param[out] plaintext Buffer where the last part of the plaintext @@ -2699,9 +2784,12 @@ psa_status_t psa_aead_finish(psa_aead_operation_t *operation, * * \retval #PSA_SUCCESS * Success. + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The calculations were successful, but the authentication tag is + * not correct. * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (not set up, nonce not set, - * encryption, or already completed). + * The operation state is not valid (it must be an active decryption + * operation with a nonce set). * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p plaintext buffer is too small. * You can determine a sufficient buffer size for \p plaintext by @@ -2740,22 +2828,15 @@ psa_status_t psa_aead_verify(psa_aead_operation_t *operation, * psa_aead_encrypt_setup() or psa_aead_decrypt_setup() again. * * You may call this function any time after the operation object has - * been initialized by any of the following methods: - * - A call to psa_aead_encrypt_setup() or psa_aead_decrypt_setup(), - * whether it succeeds or not. - * - Initializing the \c struct to all-bits-zero. - * - Initializing the \c struct to logical zeros, e.g. - * `psa_aead_operation_t operation = {0}`. + * been initialized as described in #psa_aead_operation_t. * * In particular, calling psa_aead_abort() after the operation has been - * terminated by a call to psa_aead_abort() or psa_aead_finish() - * is safe and has no effect. + * terminated by a call to psa_aead_abort(), psa_aead_finish() or + * psa_aead_verify() is safe and has no effect. * * \param[in,out] operation Initialized AEAD operation. * * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_BAD_STATE - * \p operation is not an active AEAD operation. * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_CORRUPTION_DETECTED @@ -3048,23 +3129,31 @@ static psa_key_derivation_operation_t psa_key_derivation_operation_init(void); * cryptographic material. * * To derive a key: - * - Start with an initialized object of type #psa_key_derivation_operation_t. - * - Call psa_key_derivation_setup() to select the algorithm. - * - Provide the inputs for the key derivation by calling - * psa_key_derivation_input_bytes() or psa_key_derivation_input_key() - * as appropriate. Which inputs are needed, in what order, and whether - * they may be keys and if so of what type depends on the algorithm. - * - Optionally set the operation's maximum capacity with - * psa_key_derivation_set_capacity(). You may do this before, in the middle - * of or after providing inputs. For some algorithms, this step is mandatory - * because the output depends on the maximum capacity. - * - To derive a key, call psa_key_derivation_output_key(). - * To derive a byte string for a different purpose, call - * - psa_key_derivation_output_bytes(). - * Successive calls to these functions use successive output bytes - * calculated by the key derivation algorithm. - * - Clean up the key derivation operation object with - * psa_key_derivation_abort(). + * -# Start with an initialized object of type #psa_key_derivation_operation_t. + * -# Call psa_key_derivation_setup() to select the algorithm. + * -# Provide the inputs for the key derivation by calling + * psa_key_derivation_input_bytes() or psa_key_derivation_input_key() + * as appropriate. Which inputs are needed, in what order, and whether + * they may be keys and if so of what type depends on the algorithm. + * -# Optionally set the operation's maximum capacity with + * psa_key_derivation_set_capacity(). You may do this before, in the middle + * of or after providing inputs. For some algorithms, this step is mandatory + * because the output depends on the maximum capacity. + * -# To derive a key, call psa_key_derivation_output_key(). + * To derive a byte string for a different purpose, call + * psa_key_derivation_output_bytes(). + * Successive calls to these functions use successive output bytes + * calculated by the key derivation algorithm. + * -# Clean up the key derivation operation object with + * psa_key_derivation_abort(). + * + * If this function returns an error, the key derivation operation object is + * not changed. + * + * If an error occurs at any step after a call to psa_key_derivation_setup(), + * the operation will need to be reset by a call to psa_key_derivation_abort(). + * + * Implementations must reject an attempt to derive a key of size 0. * * \param[in,out] operation The key derivation operation object * to set up. It must @@ -3085,7 +3174,7 @@ static psa_key_derivation_operation_t psa_key_derivation_operation_init(void); * \retval #PSA_ERROR_CORRUPTION_DETECTED * \retval #PSA_ERROR_STORAGE_FAILURE * \retval #PSA_ERROR_BAD_STATE - * The operation state is either not initialized or has already been setup. + * The operation state is not valid (it must be inactive). * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -3107,7 +3196,7 @@ psa_status_t psa_key_derivation_setup( * \retval #PSA_SUCCESS * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid. + * The operation state is not valid (it must be active). * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_CORRUPTION_DETECTED * \retval #PSA_ERROR_BAD_STATE @@ -3135,7 +3224,7 @@ psa_status_t psa_key_derivation_get_capacity( * In this case, the operation object remains valid and its capacity * remains unchanged. * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid. + * The operation state is not valid (it must be active). * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_CORRUPTION_DETECTED @@ -3163,9 +3252,15 @@ psa_status_t psa_key_derivation_set_capacity( * Refer to the documentation of each key derivation or key agreement * algorithm for information. * - * This function passes direct inputs. Some inputs must be passed as keys - * using psa_key_derivation_input_key() instead of this function. Refer to - * the documentation of individual step types for information. + * This function passes direct inputs, which is usually correct for + * non-secret inputs. To pass a secret input, which should be in a key + * object, call psa_key_derivation_input_key() instead of this function. + * Refer to the documentation of individual step types + * (`PSA_KEY_DERIVATION_INPUT_xxx` values of type ::psa_key_derivation_step_t) + * for more information. + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_key_derivation_abort(). * * \param[in,out] operation The key derivation operation object to use. * It must have been set up with @@ -3187,7 +3282,7 @@ psa_status_t psa_key_derivation_set_capacity( * \retval #PSA_ERROR_CORRUPTION_DETECTED * \retval #PSA_ERROR_STORAGE_FAILURE * \retval #PSA_ERROR_BAD_STATE - * The value of \p step is not valid given the state of \p operation. + * The operation state is not valid for this input \p step. * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -3205,10 +3300,16 @@ psa_status_t psa_key_derivation_input_bytes( * Refer to the documentation of each key derivation or key agreement * algorithm for information. * - * This function passes key inputs. Some inputs must be passed as keys - * of the appropriate type using this function, while others must be - * passed as direct inputs using psa_key_derivation_input_bytes(). Refer to - * the documentation of individual step types for information. + * This function obtains input from a key object, which is usually correct for + * secret inputs or for non-secret personalization strings kept in the key + * store. To pass a non-secret parameter which is not in the key store, + * call psa_key_derivation_input_bytes() instead of this function. + * Refer to the documentation of individual step types + * (`PSA_KEY_DERIVATION_INPUT_xxx` values of type ::psa_key_derivation_step_t) + * for more information. + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_key_derivation_abort(). * * \param[in,out] operation The key derivation operation object to use. * It must have been set up with @@ -3226,14 +3327,15 @@ psa_status_t psa_key_derivation_input_bytes( * \retval #PSA_ERROR_INVALID_ARGUMENT * \c step is not compatible with the operation's algorithm. * \retval #PSA_ERROR_INVALID_ARGUMENT - * \c step does not allow key inputs. + * \c step does not allow key inputs of the given type + * or does not allow key inputs at all. * \retval #PSA_ERROR_INSUFFICIENT_MEMORY * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_CORRUPTION_DETECTED * \retval #PSA_ERROR_STORAGE_FAILURE * \retval #PSA_ERROR_BAD_STATE - * The value of \p step is not valid given the state of \p operation. + * The operation state is not valid for this input \p step. * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -3253,6 +3355,9 @@ psa_status_t psa_key_derivation_input_key( * The output of this key derivation can be extracted by reading from the * resulting operation to produce keys and other cryptographic material. * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_key_derivation_abort(). + * * \param[in,out] operation The key derivation operation object to use. * It must have been set up with * psa_key_derivation_setup() with a @@ -3283,6 +3388,8 @@ psa_status_t psa_key_derivation_input_key( * * \retval #PSA_SUCCESS * Success. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid for this key agreement \p step. * \retval #PSA_ERROR_INVALID_HANDLE * \retval #PSA_ERROR_NOT_PERMITTED * \retval #PSA_ERROR_INVALID_ARGUMENT @@ -3291,6 +3398,8 @@ psa_status_t psa_key_derivation_input_key( * \c private_key. * \retval #PSA_ERROR_NOT_SUPPORTED * \c alg is not supported or is not a key derivation algorithm. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \c step does not allow an input resulting from a key agreement. * \retval #PSA_ERROR_INSUFFICIENT_MEMORY * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE @@ -3317,6 +3426,10 @@ psa_status_t psa_key_derivation_key_agreement( * stream. * The operation's capacity decreases by the number of bytes read. * + * If this function returns an error status other than + * #PSA_ERROR_INSUFFICIENT_DATA, the operation enters an error + * state and must be aborted by calling psa_key_derivation_abort(). + * * \param[in,out] operation The key derivation operation object to read from. * \param[out] output Buffer where the output will be written. * \param output_length Number of bytes to output. @@ -3330,6 +3443,8 @@ psa_status_t psa_key_derivation_key_agreement( * subsequent calls to this function will not * succeed, even with a smaller output buffer. * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active and completed + * all required input steps). * \retval #PSA_ERROR_INSUFFICIENT_MEMORY * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE @@ -3349,11 +3464,18 @@ psa_status_t psa_key_derivation_output_bytes( * * This function calculates output bytes from a key derivation algorithm * and uses those bytes to generate a key deterministically. + * The key's location, usage policy, type and size are taken from + * \p attributes. + * * If you view the key derivation's output as a stream of bytes, this * function destructively reads as many bytes as required from the * stream. * The operation's capacity decreases by the number of bytes read. * + * If this function returns an error status other than + * #PSA_ERROR_INSUFFICIENT_DATA, the operation enters an error + * state and must be aborted by calling psa_key_derivation_abort(). + * * How much output is produced and consumed from the operation, and how * the key is derived, depends on the key type: * @@ -3428,6 +3550,11 @@ psa_status_t psa_key_derivation_output_bytes( * In all cases, the data that is read is discarded from the operation. * The operation's capacity is decreased by the number of bytes read. * + * For algorithms that take an input step #PSA_KEY_DERIVATION_INPUT_SECRET, + * the input to that step must be provided with psa_key_derivation_input_key(). + * Future versions of this specification may include additional restrictions + * on the derived key based on the attributes and strength of the secret key. + * * \param[in] attributes The attributes for the new key. * \param[in,out] operation The key derivation operation object to read from. * \param[out] handle On success, a handle to the newly created key. @@ -3450,7 +3577,12 @@ psa_status_t psa_key_derivation_output_bytes( * implementation in general or in this particular location. * \retval #PSA_ERROR_INVALID_ARGUMENT * The provided key attributes are not valid for the operation. + * \retval #PSA_ERROR_NOT_PERMITTED + * The #PSA_KEY_DERIVATION_INPUT_SECRET input was not provided through + * a key. * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active and completed + * all required input steps). * \retval #PSA_ERROR_INSUFFICIENT_MEMORY * \retval #PSA_ERROR_INSUFFICIENT_STORAGE * \retval #PSA_ERROR_COMMUNICATION_FAILURE @@ -3469,22 +3601,19 @@ psa_status_t psa_key_derivation_output_key( /** Abort a key derivation operation. * - * Once a key derivation operation has been aborted, its capacity is zero. - * Aborting an operation frees all associated resources except for the - * \c operation structure itself. + * Aborting an operation frees all associated resources except for the \c + * operation structure itself. Once aborted, the operation object can be reused + * for another operation by calling psa_key_derivation_setup() again. * - * This function may be called at any time as long as the operation - * object has been initialized to #PSA_KEY_DERIVATION_OPERATION_INIT, to - * psa_key_derivation_operation_init() or a zero value. In particular, - * it is valid to call psa_key_derivation_abort() twice, or to call - * psa_key_derivation_abort() on an operation that has not been set up. + * This function may be called at any time after the operation + * object has been initialized as described in #psa_key_derivation_operation_t. * - * Once aborted, the key derivation operation object may be called. + * In particular, it is valid to call psa_key_derivation_abort() twice, or to + * call psa_key_derivation_abort() on an operation that has not been set up. * * \param[in,out] operation The operation to abort. * * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_BAD_STATE * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_CORRUPTION_DETECTED @@ -3591,7 +3720,9 @@ psa_status_t psa_generate_random(uint8_t *output, * \brief Generate a key or key pair. * * The key is generated randomly. - * Its location, policy, type and size are taken from \p attributes. + * Its location, usage policy, type and size are taken from \p attributes. + * + * Implementations must reject an attempt to generate a key of size 0. * * The following type-specific considerations apply: * - For RSA keys (#PSA_KEY_TYPE_RSA_KEY_PAIR), diff --git a/features/mbedtls/mbed-crypto/inc/psa/crypto_extra.h b/features/mbedtls/mbed-crypto/inc/psa/crypto_extra.h index 636c881102..c5313d619e 100644 --- a/features/mbedtls/mbed-crypto/inc/psa/crypto_extra.h +++ b/features/mbedtls/mbed-crypto/inc/psa/crypto_extra.h @@ -45,21 +45,14 @@ extern "C" { #if !defined(MBEDTLS_DEPRECATED_REMOVED) #define PSA_ERROR_UNKNOWN_ERROR \ MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( PSA_ERROR_GENERIC_ERROR ) -#endif - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) #define PSA_ERROR_OCCUPIED_SLOT \ MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( PSA_ERROR_ALREADY_EXISTS ) -#endif - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) #define PSA_ERROR_EMPTY_SLOT \ MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( PSA_ERROR_DOES_NOT_EXIST ) -#endif - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) #define PSA_ERROR_INSUFFICIENT_CAPACITY \ MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( PSA_ERROR_INSUFFICIENT_DATA ) +#define PSA_ERROR_TAMPERING_DETECTED \ + MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( PSA_ERROR_CORRUPTION_DETECTED ) #endif /** \addtogroup attributes @@ -193,6 +186,9 @@ static inline void psa_clear_key_slot_number( * \retval #PSA_ERROR_ALREADY_EXISTS * There is already a key with the identifier specified in * \p attributes. + * \retval #PSA_ERROR_NOT_SUPPORTED + * The secure element driver for the specified lifetime does not + * support registering a key. * \retval #PSA_ERROR_INVALID_ARGUMENT * \p attributes specifies a lifetime which is not located * in a secure element. @@ -435,8 +431,9 @@ psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed, * #PSA_KEY_TYPE_DH_KEY_PAIR(#PSA_DH_GROUP_CUSTOM), the group data comes * from domain parameters set by psa_set_key_domain_parameters(). */ -/* This value is reserved for private use in the TLS named group registry. */ -#define PSA_DH_GROUP_CUSTOM ((psa_dh_group_t) 0x01fc) +/* This value is a deprecated value meaning an explicit curve in the IANA + * registry. */ +#define PSA_DH_GROUP_CUSTOM ((psa_dh_group_t) 0xff01) /** diff --git a/features/mbedtls/mbed-crypto/inc/psa/crypto_se_driver.h b/features/mbedtls/mbed-crypto/inc/psa/crypto_se_driver.h index a43e0db48c..7ac1ed1c41 100644 --- a/features/mbedtls/mbed-crypto/inc/psa/crypto_se_driver.h +++ b/features/mbedtls/mbed-crypto/inc/psa/crypto_se_driver.h @@ -927,7 +927,14 @@ typedef psa_status_t (*psa_drv_se_allocate_key_t)( * sake of initial device provisioning or onboarding. Such a mechanism may * be added to a future version of the PSA Cryptography API specification. * + * This function may update the driver's persistent data through + * \p persistent_data. The core will save the updated persistent data at the + * end of the key creation process. See the description of + * ::psa_drv_se_allocate_key_t for more information. + * * \param[in,out] drv_context The driver context structure. + * \param[in,out] persistent_data A pointer to the persistent data + * that allows writing. * \param[in] attributes Attributes of the key. * \param method The way in which the key is being created. * \param[in] key_slot Slot where the key is to be stored. @@ -946,6 +953,7 @@ typedef psa_status_t (*psa_drv_se_allocate_key_t)( */ typedef psa_status_t (*psa_drv_se_validate_slot_number_t)( psa_drv_se_context_t *drv_context, + void *persistent_data, const psa_key_attributes_t *attributes, psa_key_creation_method_t method, psa_key_slot_number_t key_slot); diff --git a/features/mbedtls/mbed-crypto/inc/psa/crypto_types.h b/features/mbedtls/mbed-crypto/inc/psa/crypto_types.h index b79c3b5230..c4f9acd460 100644 --- a/features/mbedtls/mbed-crypto/inc/psa/crypto_types.h +++ b/features/mbedtls/mbed-crypto/inc/psa/crypto_types.h @@ -65,10 +65,82 @@ typedef int32_t psa_status_t; */ typedef uint32_t psa_key_type_t; -/** The type of PSA elliptic curve identifiers. */ +/** The type of PSA elliptic curve identifiers. + * + * The curve identifier is required to create an ECC key using the + * PSA_KEY_TYPE_ECC_KEY_PAIR() or PSA_KEY_TYPE_ECC_PUBLIC_KEY() + * macros. + * + * The encoding of curve identifiers is taken from the + * TLS Supported Groups Registry (formerly known as the + * TLS EC Named Curve Registry) + * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8 + * + * This specification defines identifiers for some of the curves in the IANA + * registry. Implementations that support other curves that are in the IANA + * registry should use the IANA value and a implementation-specific identifier. + * Implemenations that support non-IANA curves should use one of the following + * approaches for allocating a key type: + * + * 1. Select a ::psa_ecc_curve_t value in the range #PSA_ECC_CURVE_VENDOR_MIN to + * #PSA_ECC_CURVE_VENDOR_MAX, which is a subset of the IANA private use + * range. + * 2. Use a ::psa_key_type_t value that is vendor-defined. + * + * The first option is recommended. + */ typedef uint16_t psa_ecc_curve_t; -/** The type of PSA Diffie-Hellman group identifiers. */ +/** The type of PSA Diffie-Hellman group identifiers. + * + * The group identifier is required to create an Diffie-Hellman key using the + * PSA_KEY_TYPE_DH_KEY_PAIR() or PSA_KEY_TYPE_DH_PUBLIC_KEY() + * macros. + * + * The encoding of group identifiers is taken from the + * TLS Supported Groups Registry (formerly known as the + * TLS EC Named Curve Registry) + * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8 + * + * This specification defines identifiers for some of the groups in the IANA + * registry. Implementations that support other groups that are in the IANA + * registry should use the IANA value and a implementation-specific identifier. + * Implemenations that support non-IANA groups should use one of the following + * approaches for allocating a key type: + * + * 1. Select a ::psa_dh_group_t value in the range #PSA_DH_GROUP_VENDOR_MIN to + * #PSA_DH_GROUP_VENDOR_MAX, which is a subset of the IANA private use + * range. + * 2. Select a ::psa_dh_group_t value from the named groups allocated for + * GREASE in the IETF draft specification. The GREASE specification and + * values are listed below. + * 3. Use a ::psa_key_type_t value that is vendor-defined. + * + * Option 1 or 2 are recommended. + * + * The current draft of the GREASE specification is + * https://datatracker.ietf.org/doc/draft-ietf-tls-grease + * + * The following GREASE values are allocated for named groups: + * \code + * 0x0A0A + * 0x1A1A + * 0x2A2A + * 0x3A3A + * 0x4A4A + * 0x5A5A + * 0x6A6A + * 0x7A7A + * 0x8A8A + * 0x9A9A + * 0xAAAA + * 0xBABA + * 0xCACA + * 0xDADA + * 0xEAEA + * 0xFAFA + * \endcode + */ typedef uint16_t psa_dh_group_t; /** \brief Encoding of a cryptographic algorithm. @@ -206,11 +278,12 @@ typedef uint32_t psa_key_usage_t; * values: * * - lifetime: #PSA_KEY_LIFETIME_VOLATILE. - * - key identifier: unspecified. - * - type: \c 0. - * - key size: \c 0. - * - usage flags: \c 0. - * - algorithm: \c 0. + * - key identifier: 0 (which is not a valid key identifier). + * - type: \c 0 (meaning that the type is unspecified). + * - key size: \c 0 (meaning that the size is unspecified). + * - usage flags: \c 0 (which allows no usage except exporting a public key). + * - algorithm: \c 0 (which allows no cryptographic usage, but allows + * exporting). * * A typical sequence to create a key is as follows: * -# Create and initialize an attribute structure. diff --git a/features/mbedtls/mbed-crypto/inc/psa/crypto_values.h b/features/mbedtls/mbed-crypto/inc/psa/crypto_values.h index b53e1c769c..1e0c2136a0 100644 --- a/features/mbedtls/mbed-crypto/inc/psa/crypto_values.h +++ b/features/mbedtls/mbed-crypto/inc/psa/crypto_values.h @@ -149,7 +149,7 @@ * * \warning If a function returns this error, it is undetermined * whether the requested action has completed or not. Implementations - * should return #PSA_SUCCESS on successful completion whenver + * should return #PSA_SUCCESS on successful completion whenever * possible, however functions may return #PSA_ERROR_COMMUNICATION_FAILURE * if the requested action was completed successfully in an external * cryptoprocessor but there was a breakdown of communication before @@ -284,7 +284,7 @@ */ #define PSA_KEY_TYPE_NONE ((psa_key_type_t)0x00000000) -/** Vendor-defined flag +/** Vendor-defined key type flag. * * Key types defined by this standard will never have the * #PSA_KEY_TYPE_VENDOR_FLAG bit set. Vendors who define additional key types @@ -301,7 +301,10 @@ #define PSA_KEY_TYPE_CATEGORY_FLAG_PAIR ((psa_key_type_t)0x10000000) -/** Whether a key type is vendor-defined. */ +/** Whether a key type is vendor-defined. + * + * See also #PSA_KEY_TYPE_VENDOR_FLAG. + */ #define PSA_KEY_TYPE_IS_VENDOR_DEFINED(type) \ (((type) & PSA_KEY_TYPE_VENDOR_FLAG) != 0) @@ -421,10 +424,18 @@ #define PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE ((psa_key_type_t)0x60030000) #define PSA_KEY_TYPE_ECC_KEY_PAIR_BASE ((psa_key_type_t)0x70030000) #define PSA_KEY_TYPE_ECC_CURVE_MASK ((psa_key_type_t)0x0000ffff) -/** Elliptic curve key pair. */ +/** Elliptic curve key pair. + * + * \param curve A value of type ::psa_ecc_curve_t that identifies the + * ECC curve to be used. + */ #define PSA_KEY_TYPE_ECC_KEY_PAIR(curve) \ (PSA_KEY_TYPE_ECC_KEY_PAIR_BASE | (curve)) -/** Elliptic curve public key. */ +/** Elliptic curve public key. + * + * \param curve A value of type ::psa_ecc_curve_t that identifies the + * ECC curve to be used. + */ #define PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve) \ (PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE | (curve)) @@ -495,13 +506,34 @@ */ #define PSA_ECC_CURVE_CURVE448 ((psa_ecc_curve_t) 0x001e) +/** Minimum value for a vendor-defined ECC curve identifier + * + * The range for vendor-defined curve identifiers is a subset of the IANA + * registry private use range, `0xfe00` - `0xfeff`. + */ +#define PSA_ECC_CURVE_VENDOR_MIN ((psa_ecc_curve_t) 0xfe00) +/** Maximum value for a vendor-defined ECC curve identifier + * + * The range for vendor-defined curve identifiers is a subset of the IANA + * registry private use range, `0xfe00` - `0xfeff`. + */ +#define PSA_ECC_CURVE_VENDOR_MAX ((psa_ecc_curve_t) 0xfe7f) + #define PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE ((psa_key_type_t)0x60040000) #define PSA_KEY_TYPE_DH_KEY_PAIR_BASE ((psa_key_type_t)0x70040000) #define PSA_KEY_TYPE_DH_GROUP_MASK ((psa_key_type_t)0x0000ffff) -/** Diffie-Hellman key pair. */ +/** Diffie-Hellman key pair. + * + * \param group A value of type ::psa_dh_group_t that identifies the + * Diffie-Hellman group to be used. + */ #define PSA_KEY_TYPE_DH_KEY_PAIR(group) \ (PSA_KEY_TYPE_DH_KEY_PAIR_BASE | (group)) -/** Diffie-Hellman public key. */ +/** Diffie-Hellman public key. + * + * \param group A value of type ::psa_dh_group_t that identifies the + * Diffie-Hellman group to be used. + */ #define PSA_KEY_TYPE_DH_PUBLIC_KEY(group) \ (PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE | (group)) @@ -535,6 +567,19 @@ #define PSA_DH_GROUP_FFDHE6144 ((psa_dh_group_t) 0x0103) #define PSA_DH_GROUP_FFDHE8192 ((psa_dh_group_t) 0x0104) +/** Minimum value for a vendor-defined Diffie Hellman group identifier + * + * The range for vendor-defined group identifiers is a subset of the IANA + * registry private use range, `0x01fc` - `0x01ff`. + */ +#define PSA_DH_GROUP_VENDOR_MIN ((psa_dh_group_t) 0x01fc) +/** Maximum value for a vendor-defined Diffie Hellman group identifier + * + * The range for vendor-defined group identifiers is a subset of the IANA + * registry private use range, `0x01fc` - `0x01ff`. + */ +#define PSA_DH_GROUP_VENDOR_MAX ((psa_dh_group_t) 0x01fd) + /** The block size of a block cipher. * * \param type A cipher key type (value of type #psa_key_type_t). @@ -561,7 +606,15 @@ (type) == PSA_KEY_TYPE_ARC4 ? 1 : \ 0) +/** Vendor-defined algorithm flag. + * + * Algorithms defined by this standard will never have the #PSA_ALG_VENDOR_FLAG + * bit set. Vendors who define additional algorithms must use an encoding with + * the #PSA_ALG_VENDOR_FLAG bit set and should respect the bitwise structure + * used by standard encodings whenever practical. + */ #define PSA_ALG_VENDOR_FLAG ((psa_algorithm_t)0x80000000) + #define PSA_ALG_CATEGORY_MASK ((psa_algorithm_t)0x7f000000) #define PSA_ALG_CATEGORY_HASH ((psa_algorithm_t)0x01000000) #define PSA_ALG_CATEGORY_MAC ((psa_algorithm_t)0x02000000) @@ -572,6 +625,10 @@ #define PSA_ALG_CATEGORY_KEY_DERIVATION ((psa_algorithm_t)0x20000000) #define PSA_ALG_CATEGORY_KEY_AGREEMENT ((psa_algorithm_t)0x30000000) +/** Whether an algorithm is vendor-defined. + * + * See also #PSA_ALG_VENDOR_FLAG. + */ #define PSA_ALG_IS_VENDOR_DEFINED(alg) \ (((alg) & PSA_ALG_VENDOR_FLAG) != 0) @@ -665,11 +722,15 @@ (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_DERIVATION) #define PSA_ALG_HASH_MASK ((psa_algorithm_t)0x000000ff) - +/** MD2 */ #define PSA_ALG_MD2 ((psa_algorithm_t)0x01000001) +/** MD4 */ #define PSA_ALG_MD4 ((psa_algorithm_t)0x01000002) +/** MD5 */ #define PSA_ALG_MD5 ((psa_algorithm_t)0x01000003) +/** PSA_ALG_RIPEMD160 */ #define PSA_ALG_RIPEMD160 ((psa_algorithm_t)0x01000004) +/** SHA1 */ #define PSA_ALG_SHA_1 ((psa_algorithm_t)0x01000005) /** SHA2-224 */ #define PSA_ALG_SHA_224 ((psa_algorithm_t)0x01000008) @@ -1603,31 +1664,43 @@ /** A secret input for key derivation. * - * This must be a key of type #PSA_KEY_TYPE_DERIVE. + * This should be a key of type #PSA_KEY_TYPE_DERIVE + * (passed to psa_key_derivation_input_key()) + * or the shared secret resulting from a key agreement + * (obtained via psa_key_derivation_key_agreement()). + * + * The secret can also be a direct input (passed to + * key_derivation_input_bytes()). In this case, the derivation operation + * may not be used to derive keys: the operation will only allow + * psa_key_derivation_output_bytes(), not psa_key_derivation_output_key(). */ #define PSA_KEY_DERIVATION_INPUT_SECRET ((psa_key_derivation_step_t)0x0101) /** A label for key derivation. * - * This must be a direct input. + * This should be a direct input. + * It can also be a key of type #PSA_KEY_TYPE_RAW_DATA. */ #define PSA_KEY_DERIVATION_INPUT_LABEL ((psa_key_derivation_step_t)0x0201) /** A salt for key derivation. * - * This must be a direct input. + * This should be a direct input. + * It can also be a key of type #PSA_KEY_TYPE_RAW_DATA. */ #define PSA_KEY_DERIVATION_INPUT_SALT ((psa_key_derivation_step_t)0x0202) /** An information string for key derivation. * - * This must be a direct input. + * This should be a direct input. + * It can also be a key of type #PSA_KEY_TYPE_RAW_DATA. */ #define PSA_KEY_DERIVATION_INPUT_INFO ((psa_key_derivation_step_t)0x0203) /** A seed for key derivation. * - * This must be a direct input. + * This should be a direct input. + * It can also be a key of type #PSA_KEY_TYPE_RAW_DATA. */ #define PSA_KEY_DERIVATION_INPUT_SEED ((psa_key_derivation_step_t)0x0204) diff --git a/features/mbedtls/mbed-crypto/platform/COMPONENT_PSA_SRV_IMPL/COMPONENT_NSPE/crypto_struct.h b/features/mbedtls/mbed-crypto/platform/COMPONENT_PSA_SRV_IMPL/COMPONENT_NSPE/crypto_struct.h index f177d5d919..9f55484e2f 100644 --- a/features/mbedtls/mbed-crypto/platform/COMPONENT_PSA_SRV_IMPL/COMPONENT_NSPE/crypto_struct.h +++ b/features/mbedtls/mbed-crypto/platform/COMPONENT_PSA_SRV_IMPL/COMPONENT_NSPE/crypto_struct.h @@ -255,6 +255,7 @@ typedef struct psa_tls12_prf_key_derivation_s struct psa_key_derivation_s { psa_algorithm_t alg; + unsigned int can_output_key : 1; size_t capacity; union { @@ -268,7 +269,7 @@ struct psa_key_derivation_s }; /* This only zeroes out the first byte in the union, the rest is unspecified. */ -#define PSA_KEY_DERIVATION_OPERATION_INIT {0, 0, {0}} +#define PSA_KEY_DERIVATION_OPERATION_INIT {0, 0, 0, {0}} static inline struct psa_key_derivation_s psa_key_derivation_operation_init( void ) { const struct psa_key_derivation_s v = PSA_KEY_DERIVATION_OPERATION_INIT; diff --git a/features/mbedtls/mbed-crypto/platform/COMPONENT_PSA_SRV_IMPL/psa_crypto.c b/features/mbedtls/mbed-crypto/platform/COMPONENT_PSA_SRV_IMPL/psa_crypto.c index a80f13de3f..42c2969bfd 100644 --- a/features/mbedtls/mbed-crypto/platform/COMPONENT_PSA_SRV_IMPL/psa_crypto.c +++ b/features/mbedtls/mbed-crypto/platform/COMPONENT_PSA_SRV_IMPL/psa_crypto.c @@ -451,13 +451,6 @@ static psa_status_t prepare_raw_data_slot( psa_key_type_t type, switch( type ) { case PSA_KEY_TYPE_RAW_DATA: - if( bits == 0 ) - { - raw->bytes = 0; - raw->data = NULL; - return( PSA_SUCCESS ); - } - break; #if defined(MBEDTLS_MD_C) case PSA_KEY_TYPE_HMAC: #endif @@ -1020,6 +1013,9 @@ psa_status_t psa_destroy_key( psa_key_handle_t handle ) psa_se_drv_table_entry_t *driver; #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ + if( handle == 0 ) + return( PSA_SUCCESS ); + status = psa_get_key_slot( handle, &slot ); if( status != PSA_SUCCESS ) return( status ); @@ -1281,6 +1277,12 @@ static psa_status_t psa_internal_export_key( const psa_key_slot_t *slot, if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->attr.type ) ) return( PSA_ERROR_INVALID_ARGUMENT ); + /* Reject a zero-length output buffer now, since this can never be a + * valid key representation. This way we know that data must be a valid + * pointer and we can do things like memset(data, ..., data_size). */ + if( data_size == 0 ) + return( PSA_ERROR_BUFFER_TOO_SMALL ); + #if defined(MBEDTLS_PSA_CRYPTO_SE_C) if( psa_get_se_driver( slot->attr.lifetime, &drv, &drv_context ) ) { @@ -1302,12 +1304,9 @@ static psa_status_t psa_internal_export_key( const psa_key_slot_t *slot, { if( slot->data.raw.bytes > data_size ) return( PSA_ERROR_BUFFER_TOO_SMALL ); - if( data_size != 0 ) - { - memcpy( data, slot->data.raw.data, slot->data.raw.bytes ); - memset( data + slot->data.raw.bytes, 0, - data_size - slot->data.raw.bytes ); - } + memcpy( data, slot->data.raw.data, slot->data.raw.bytes ); + memset( data + slot->data.raw.bytes, 0, + data_size - slot->data.raw.bytes ); *data_length = slot->data.raw.bytes; return( PSA_SUCCESS ); } @@ -1366,10 +1365,7 @@ static psa_status_t psa_internal_export_key( const psa_key_slot_t *slot, } if( ret < 0 ) { - /* If data_size is 0 then data may be NULL and then the - * call to memset would have undefined behavior. */ - if( data_size != 0 ) - memset( data, 0, data_size ); + memset( data, 0, data_size ); return( mbedtls_to_psa_error( ret ) ); } /* The mbedtls_pk_xxx functions write to the end of the buffer. @@ -1586,7 +1582,7 @@ static psa_status_t psa_start_key_creation( #if defined(MBEDTLS_PSA_CRYPTO_SE_C) /* For a key in a secure element, we need to do three things - * when creating a key (but not when registering an existing key): + * when creating or registering a key: * create the key file in internal storage, create the * key inside the secure element, and update the driver's * persistent data. Start a transaction that will encompass these @@ -1599,7 +1595,7 @@ static psa_status_t psa_start_key_creation( * secure element driver updates its persistent state, but we do not yet * save the driver's persistent state, so that if the power fails, * we can roll back to a state where the key doesn't exist. */ - if( *p_drv != NULL && method != PSA_KEY_CREATION_REGISTER ) + if( *p_drv != NULL ) { status = psa_find_se_slot_for_key( attributes, method, *p_drv, &slot->data.se.slot_number ); @@ -1616,6 +1612,12 @@ static psa_status_t psa_start_key_creation( return( status ); } } + + if( *p_drv == NULL && method == PSA_KEY_CREATION_REGISTER ) + { + /* Key registration only makes sense with a secure element. */ + return( PSA_ERROR_INVALID_ARGUMENT ); + } #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ return( status ); @@ -1676,7 +1678,7 @@ static psa_status_t psa_finish_key_creation( slot->attr.bits ); uint8_t *buffer = mbedtls_calloc( 1, buffer_size ); size_t length = 0; - if( buffer == NULL && buffer_size != 0 ) + if( buffer == NULL ) return( PSA_ERROR_INSUFFICIENT_MEMORY ); status = psa_internal_export_key( slot, buffer, buffer_size, &length, @@ -1685,8 +1687,7 @@ static psa_status_t psa_finish_key_creation( status = psa_save_persistent_key( &slot->attr, buffer, length ); - if( buffer_size != 0 ) - mbedtls_platform_zeroize( buffer, buffer_size ); + mbedtls_platform_zeroize( buffer, buffer_size ); mbedtls_free( buffer ); } } @@ -1826,6 +1827,12 @@ psa_status_t psa_import_key( const psa_key_attributes_t *attributes, psa_key_slot_t *slot = NULL; psa_se_drv_table_entry_t *driver = NULL; + /* Reject zero-length symmetric keys (including raw data key objects). + * This also rejects any key which might be encoded as an empty string, + * which is never valid. */ + if( data_length == 0 ) + return( PSA_ERROR_INVALID_ARGUMENT ); + status = psa_start_key_creation( PSA_KEY_CREATION_IMPORT, attributes, handle, &slot, &driver ); if( status != PSA_SUCCESS ) @@ -1885,7 +1892,6 @@ psa_status_t mbedtls_psa_register_se_key( psa_status_t status; psa_key_slot_t *slot = NULL; psa_se_drv_table_entry_t *driver = NULL; - const psa_drv_se_t *drv; psa_key_handle_t handle = 0; /* Leaving attributes unspecified is not currently supported. @@ -1902,37 +1908,6 @@ psa_status_t mbedtls_psa_register_se_key( if( status != PSA_SUCCESS ) goto exit; - if( driver == NULL ) - { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - drv = psa_get_se_driver_methods( driver ); - - if ( psa_get_key_slot_number( attributes, - &slot->data.se.slot_number ) != PSA_SUCCESS ) - { - /* The application didn't specify a slot number. This doesn't - * make sense when registering a slot. */ - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - - /* If the driver has a slot number validation method, call it. - * If it doesn't, it means the secure element is unable to validate - * anything and so we have to trust the application. */ - if( drv->key_management != NULL && - drv->key_management->p_validate_slot_number != NULL ) - { - status = drv->key_management->p_validate_slot_number( - psa_get_se_driver_context( driver ), - attributes, - PSA_KEY_CREATION_REGISTER, - slot->data.se.slot_number ); - if( status != PSA_SUCCESS ) - goto exit; - } - status = psa_finish_key_creation( slot, driver ); exit: @@ -1957,7 +1932,7 @@ static psa_status_t psa_copy_key_material( const psa_key_slot_t *source, buffer_size = PSA_KEY_EXPORT_MAX_SIZE( source->attr.type, psa_get_key_slot_bits( source ) ); buffer = mbedtls_calloc( 1, buffer_size ); - if( buffer == NULL && buffer_size != 0 ) + if( buffer == NULL ) return( PSA_ERROR_INSUFFICIENT_MEMORY ); status = psa_internal_export_key( source, buffer, buffer_size, &length, 0 ); if( status != PSA_SUCCESS ) @@ -1966,8 +1941,7 @@ static psa_status_t psa_copy_key_material( const psa_key_slot_t *source, status = psa_import_key_into_slot( target, buffer, length ); exit: - if( buffer_size != 0 ) - mbedtls_platform_zeroize( buffer, buffer_size ); + mbedtls_platform_zeroize( buffer, buffer_size ); mbedtls_free( buffer ); return( status ); } @@ -2735,7 +2709,7 @@ static psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac, status = psa_hash_update( &hmac->hash_ctx, ipad, block_size ); cleanup: - mbedtls_platform_zeroize( ipad, key_length ); + mbedtls_platform_zeroize( ipad, sizeof(ipad) ); return( status ); } @@ -3194,8 +3168,8 @@ static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa, if( status != PSA_SUCCESS ) return( status ); - if( signature_length < mbedtls_rsa_get_len( rsa ) ) - return( PSA_ERROR_BUFFER_TOO_SMALL ); + if( signature_length != mbedtls_rsa_get_len( rsa ) ) + return( PSA_ERROR_INVALID_SIGNATURE ); #if defined(MBEDTLS_PKCS1_V15) if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) ) @@ -3350,6 +3324,12 @@ psa_status_t psa_asymmetric_sign( psa_key_handle_t handle, #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ *signature_length = signature_size; + /* Immediately reject a zero-length signature buffer. This guarantees + * that signature must be a valid pointer. (On the other hand, the hash + * buffer can in principle be empty since it doesn't actually have + * to be a hash.) */ + if( signature_size == 0 ) + return( PSA_ERROR_BUFFER_TOO_SMALL ); status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_SIGN, alg ); if( status != PSA_SUCCESS ) @@ -3425,7 +3405,7 @@ exit: if( status == PSA_SUCCESS ) memset( signature + *signature_length, '!', signature_size - *signature_length ); - else if( signature_size != 0 ) + else memset( signature, '!', signature_size ); /* If signature_size is 0 then we have nothing to do. We must not call * memset because signature may be NULL in this case. */ @@ -4778,6 +4758,15 @@ psa_status_t psa_key_derivation_output_key( const psa_key_attributes_t *attribut psa_status_t status; psa_key_slot_t *slot = NULL; psa_se_drv_table_entry_t *driver = NULL; + + /* Reject any attempt to create a zero-length key so that we don't + * risk tripping up later, e.g. on a malloc(0) that returns NULL. */ + if( psa_get_key_bits( attributes ) == 0 ) + return( PSA_ERROR_INVALID_ARGUMENT ); + + if( ! operation->can_output_key ) + return( PSA_ERROR_NOT_PERMITTED ); + status = psa_start_key_creation( PSA_KEY_CREATION_DERIVE, attributes, handle, &slot, &driver ); #if defined(MBEDTLS_PSA_CRYPTO_SE_C) @@ -5067,15 +5056,54 @@ static psa_status_t psa_tls12_prf_psk_to_ms_input( } #endif /* MBEDTLS_MD_C */ +/** Check whether the given key type is acceptable for the given + * input step of a key derivation. + * + * Secret inputs must have the type #PSA_KEY_TYPE_DERIVE. + * Non-secret inputs must have the type #PSA_KEY_TYPE_RAW_DATA. + * Both secret and non-secret inputs can alternatively have the type + * #PSA_KEY_TYPE_NONE, which is never the type of a key object, meaning + * that the input was passed as a buffer rather than via a key object. + */ +static int psa_key_derivation_check_input_type( + psa_key_derivation_step_t step, + psa_key_type_t key_type ) +{ + switch( step ) + { + case PSA_KEY_DERIVATION_INPUT_SECRET: + if( key_type == PSA_KEY_TYPE_DERIVE ) + return( PSA_SUCCESS ); + if( key_type == PSA_KEY_TYPE_NONE ) + return( PSA_SUCCESS ); + break; + case PSA_KEY_DERIVATION_INPUT_LABEL: + case PSA_KEY_DERIVATION_INPUT_SALT: + case PSA_KEY_DERIVATION_INPUT_INFO: + case PSA_KEY_DERIVATION_INPUT_SEED: + if( key_type == PSA_KEY_TYPE_RAW_DATA ) + return( PSA_SUCCESS ); + if( key_type == PSA_KEY_TYPE_NONE ) + return( PSA_SUCCESS ); + break; + } + return( PSA_ERROR_INVALID_ARGUMENT ); +} + static psa_status_t psa_key_derivation_input_internal( psa_key_derivation_operation_t *operation, psa_key_derivation_step_t step, + psa_key_type_t key_type, const uint8_t *data, size_t data_length ) { psa_status_t status; psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg( operation ); + status = psa_key_derivation_check_input_type( step, key_type ); + if( status != PSA_SUCCESS ) + goto exit; + #if defined(MBEDTLS_MD_C) if( PSA_ALG_IS_HKDF( kdf_alg ) ) { @@ -5102,6 +5130,7 @@ static psa_status_t psa_key_derivation_input_internal( return( PSA_ERROR_BAD_STATE ); } +exit: if( status != PSA_SUCCESS ) psa_key_derivation_abort( operation ); return( status ); @@ -5113,10 +5142,8 @@ psa_status_t psa_key_derivation_input_bytes( const uint8_t *data, size_t data_length ) { - if( step == PSA_KEY_DERIVATION_INPUT_SECRET ) - return( PSA_ERROR_INVALID_ARGUMENT ); - return( psa_key_derivation_input_internal( operation, step, + PSA_KEY_TYPE_NONE, data, data_length ) ); } @@ -5127,23 +5154,23 @@ psa_status_t psa_key_derivation_input_key( { psa_key_slot_t *slot; psa_status_t status; + status = psa_get_transparent_key( handle, &slot, PSA_KEY_USAGE_DERIVE, operation->alg ); if( status != PSA_SUCCESS ) + { + psa_key_derivation_abort( operation ); return( status ); - if( slot->attr.type != PSA_KEY_TYPE_DERIVE ) - return( PSA_ERROR_INVALID_ARGUMENT ); - /* Don't allow a key to be used as an input that is usually public. - * This is debatable. It's ok from a cryptographic perspective to - * use secret material as an input that is usually public. However - * the material should be dedicated to a particular input step, - * otherwise this may allow the key to be used in an unintended way - * and leak values derived from the key. So be conservative. */ - if( step != PSA_KEY_DERIVATION_INPUT_SECRET ) - return( PSA_ERROR_INVALID_ARGUMENT ); + } + + /* Passing a key object as a SECRET input unlocks the permission + * to output to a key object. */ + if( step == PSA_KEY_DERIVATION_INPUT_SECRET ) + operation->can_output_key = 1; + return( psa_key_derivation_input_internal( operation, - step, + step, slot->attr.type, slot->data.raw.data, slot->data.raw.bytes ) ); } @@ -5256,8 +5283,10 @@ static psa_status_t psa_key_agreement_internal( psa_key_derivation_operation_t * goto exit; /* Step 2: set up the key derivation to generate key material from - * the shared secret. */ + * the shared secret. A shared secret is permitted wherever a key + * of type DERIVE is permitted. */ status = psa_key_derivation_input_internal( operation, step, + PSA_KEY_TYPE_DERIVE, shared_secret, shared_secret_length ); @@ -5512,6 +5541,11 @@ psa_status_t psa_generate_key( const psa_key_attributes_t *attributes, psa_key_slot_t *slot = NULL; psa_se_drv_table_entry_t *driver = NULL; + /* Reject any attempt to create a zero-length key so that we don't + * risk tripping up later, e.g. on a malloc(0) that returns NULL. */ + if( psa_get_key_bits( attributes ) == 0 ) + return( PSA_ERROR_INVALID_ARGUMENT ); + status = psa_start_key_creation( PSA_KEY_CREATION_GENERATE, attributes, handle, &slot, &driver ); if( status != PSA_SUCCESS ) @@ -5656,6 +5690,12 @@ psa_status_t psa_crypto_init( void ) if( status != PSA_SUCCESS ) goto exit; +#if defined(MBEDTLS_PSA_CRYPTO_SE_C) + status = psa_init_all_se_drivers( ); + if( status != PSA_SUCCESS ) + goto exit; +#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ + #if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS) status = psa_crypto_load_transaction( ); if( status == PSA_SUCCESS ) diff --git a/features/mbedtls/mbed-crypto/platform/COMPONENT_PSA_SRV_IMPL/psa_crypto_se.c b/features/mbedtls/mbed-crypto/platform/COMPONENT_PSA_SRV_IMPL/psa_crypto_se.c index 523c621058..b7fa0c5c5e 100644 --- a/features/mbedtls/mbed-crypto/platform/COMPONENT_PSA_SRV_IMPL/psa_crypto_se.c +++ b/features/mbedtls/mbed-crypto/platform/COMPONENT_PSA_SRV_IMPL/psa_crypto_se.c @@ -222,9 +222,16 @@ psa_status_t psa_find_se_slot_for_key( if( p_validate_slot_number == NULL ) return( PSA_ERROR_NOT_SUPPORTED ); status = p_validate_slot_number( &driver->context, + driver->internal.persistent_data, attributes, method, *slot_number ); } + else if( method == PSA_KEY_CREATION_REGISTER ) + { + /* The application didn't specify a slot number. This doesn't + * make sense when registering a slot. */ + return( PSA_ERROR_INVALID_ARGUMENT ); + } else { /* The application didn't tell us which slot to use. Let the driver @@ -265,6 +272,31 @@ psa_status_t psa_destroy_se_key( psa_se_drv_table_entry_t *driver, return( status == PSA_SUCCESS ? storage_status : status ); } +psa_status_t psa_init_all_se_drivers( void ) +{ + size_t i; + for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ ) + { + psa_se_drv_table_entry_t *driver = &driver_table[i]; + if( driver->lifetime == 0 ) + continue; /* skipping unused entry */ + const psa_drv_se_t *methods = psa_get_se_driver_methods( driver ); + if( methods->p_init != NULL ) + { + psa_status_t status = methods->p_init( + &driver->context, + driver->internal.persistent_data, + driver->lifetime ); + if( status != PSA_SUCCESS ) + return( status ); + status = psa_save_se_persistent_data( driver ); + if( status != PSA_SUCCESS ) + return( status ); + } + } + return( PSA_SUCCESS ); +} + /****************************************************************/ @@ -309,6 +341,8 @@ psa_status_t psa_register_se_driver( driver_table[i].lifetime = lifetime; driver_table[i].methods = methods; + driver_table[i].internal.persistent_data_size = + methods->persistent_data_size; if( methods->persistent_data_size != 0 ) { @@ -326,8 +360,6 @@ psa_status_t psa_register_se_driver( if( status != PSA_SUCCESS && status != PSA_ERROR_DOES_NOT_EXIST ) goto error; } - driver_table[i].internal.persistent_data_size = - methods->persistent_data_size; return( PSA_SUCCESS ); diff --git a/features/mbedtls/mbed-crypto/platform/COMPONENT_PSA_SRV_IMPL/psa_crypto_se.h b/features/mbedtls/mbed-crypto/platform/COMPONENT_PSA_SRV_IMPL/psa_crypto_se.h index 900a72bd3c..86bf7a7b1a 100644 --- a/features/mbedtls/mbed-crypto/platform/COMPONENT_PSA_SRV_IMPL/psa_crypto_se.h +++ b/features/mbedtls/mbed-crypto/platform/COMPONENT_PSA_SRV_IMPL/psa_crypto_se.h @@ -66,6 +66,12 @@ */ void psa_unregister_all_se_drivers( void ); +/** Initialize all secure element drivers. + * + * Called from psa_crypto_init(). + */ +psa_status_t psa_init_all_se_drivers( void ); + /** A structure that describes a registered secure element driver. * * A secure element driver table entry contains a pointer to the diff --git a/features/mbedtls/mbed-crypto/platform/COMPONENT_PSA_SRV_IMPL/psa_crypto_slot_management.c b/features/mbedtls/mbed-crypto/platform/COMPONENT_PSA_SRV_IMPL/psa_crypto_slot_management.c index 59be319ce6..6cd6a1135b 100644 --- a/features/mbedtls/mbed-crypto/platform/COMPONENT_PSA_SRV_IMPL/psa_crypto_slot_management.c +++ b/features/mbedtls/mbed-crypto/platform/COMPONENT_PSA_SRV_IMPL/psa_crypto_slot_management.c @@ -255,6 +255,9 @@ psa_status_t psa_close_key( psa_key_handle_t handle ) psa_status_t status; psa_key_slot_t *slot; + if( handle == 0 ) + return( PSA_SUCCESS ); + status = psa_get_key_slot( handle, &slot ); if( status != PSA_SUCCESS ) return( status ); diff --git a/features/mbedtls/mbed-crypto/platform/COMPONENT_SPE/crypto_struct_spe.h b/features/mbedtls/mbed-crypto/platform/COMPONENT_SPE/crypto_struct_spe.h index 1ecfbfb8d9..fa0466e6ca 100644 --- a/features/mbedtls/mbed-crypto/platform/COMPONENT_SPE/crypto_struct_spe.h +++ b/features/mbedtls/mbed-crypto/platform/COMPONENT_SPE/crypto_struct_spe.h @@ -255,6 +255,7 @@ typedef struct psa_tls12_prf_key_derivation_s struct psa_key_derivation_s { psa_algorithm_t alg; + unsigned int can_output_key : 1; size_t capacity; union { @@ -268,7 +269,7 @@ struct psa_key_derivation_s }; /* This only zeroes out the first byte in the union, the rest is unspecified. */ -#define PSA_KEY_DERIVATION_OPERATION_INIT {0, 0, {0}} +#define PSA_KEY_DERIVATION_OPERATION_INIT {0, 0, 0, {0}} static inline struct psa_key_derivation_s psa_key_derivation_operation_init( void ) { const struct psa_key_derivation_s v = PSA_KEY_DERIVATION_OPERATION_INIT; diff --git a/features/mbedtls/mbed-crypto/src/asn1parse.c b/features/mbedtls/mbed-crypto/src/asn1parse.c index 171c340b8c..412259e358 100644 --- a/features/mbedtls/mbed-crypto/src/asn1parse.c +++ b/features/mbedtls/mbed-crypto/src/asn1parse.c @@ -149,11 +149,28 @@ int mbedtls_asn1_get_int( unsigned char **p, if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) return( ret ); - if( len == 0 || len > sizeof( int ) || ( **p & 0x80 ) != 0 ) + /* len==0 is malformed (0 must be represented as 020100). */ + if( len == 0 ) + return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); + /* This is a cryptography library. Reject negative integers. */ + if( ( **p & 0x80 ) != 0 ) + return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); + + /* Skip leading zeros. */ + while( len > 0 && **p == 0 ) + { + ++( *p ); + --len; + } + + /* Reject integers that don't fit in an int. This code assumes that + * the int type has no padding bit. */ + if( len > sizeof( int ) ) + return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); + if( len == sizeof( int ) && ( **p & 0x80 ) != 0 ) return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); *val = 0; - while( len-- > 0 ) { *val = ( *val << 8 ) | **p; @@ -223,8 +240,13 @@ int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end if( ( ret = mbedtls_asn1_get_tag( p, end, len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 ) return( ret ); - if( (*len)-- < 2 || *(*p)++ != 0 ) + if( *len == 0 ) return( MBEDTLS_ERR_ASN1_INVALID_DATA ); + --( *len ); + + if( **p != 0 ) + return( MBEDTLS_ERR_ASN1_INVALID_DATA ); + ++( *p ); return( 0 ); } diff --git a/features/mbedtls/mbed-crypto/src/asn1write.c b/features/mbedtls/mbed-crypto/src/asn1write.c index b54e26bd8a..a138d0b75c 100644 --- a/features/mbedtls/mbed-crypto/src/asn1write.c +++ b/features/mbedtls/mbed-crypto/src/asn1write.c @@ -236,17 +236,20 @@ int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val ) int ret; size_t len = 0; - if( *p - start < 1 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - len += 1; - *--(*p) = val; - - if( val > 0 && **p & 0x80 ) + do { if( *p - start < 1 ) return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + len += 1; + *--(*p) = val & 0xff; + val >>= 8; + } + while( val > 0 ); + if( **p & 0x80 ) + { + if( *p - start < 1 ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); *--(*p) = 0x00; len += 1; } @@ -429,18 +432,26 @@ mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( memcpy( cur->oid.p, oid, oid_len ); cur->val.len = val_len; - cur->val.p = mbedtls_calloc( 1, val_len ); - if( cur->val.p == NULL ) + if( val_len != 0 ) { - mbedtls_free( cur->oid.p ); - mbedtls_free( cur ); - return( NULL ); + cur->val.p = mbedtls_calloc( 1, val_len ); + if( cur->val.p == NULL ) + { + mbedtls_free( cur->oid.p ); + mbedtls_free( cur ); + return( NULL ); + } } cur->next = *head; *head = cur; } - else if( cur->val.len < val_len ) + else if( val_len == 0 ) + { + mbedtls_free( cur->val.p ); + cur->val.p = NULL; + } + else if( cur->val.len != val_len ) { /* * Enlarge existing value buffer if needed diff --git a/features/mbedtls/mbed-crypto/src/ecp_curves.c b/features/mbedtls/mbed-crypto/src/ecp_curves.c index 282481d053..dcc70739d0 100644 --- a/features/mbedtls/mbed-crypto/src/ecp_curves.c +++ b/features/mbedtls/mbed-crypto/src/ecp_curves.c @@ -836,7 +836,7 @@ int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id ) #endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */ default: - mbedtls_ecp_group_free( grp ); + grp->id = MBEDTLS_ECP_DP_NONE; return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); } } diff --git a/features/mbedtls/mbed-crypto/src/md.c b/features/mbedtls/mbed-crypto/src/md.c index ac8fac5bb5..e1b5183b6a 100644 --- a/features/mbedtls/mbed-crypto/src/md.c +++ b/features/mbedtls/mbed-crypto/src/md.c @@ -35,6 +35,14 @@ #include "mbedtls/md_internal.h" #include "mbedtls/platform_util.h" +#include "mbedtls/md2.h" +#include "mbedtls/md4.h" +#include "mbedtls/md5.h" +#include "mbedtls/ripemd160.h" +#include "mbedtls/sha1.h" +#include "mbedtls/sha256.h" +#include "mbedtls/sha512.h" + #if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" #else @@ -49,6 +57,83 @@ #include #endif +#if defined(MBEDTLS_MD2_C) +const mbedtls_md_info_t mbedtls_md2_info = { + "MD2", + MBEDTLS_MD_MD2, + 16, + 16, +}; +#endif + +#if defined(MBEDTLS_MD4_C) +const mbedtls_md_info_t mbedtls_md4_info = { + "MD4", + MBEDTLS_MD_MD4, + 16, + 64, +}; +#endif + +#if defined(MBEDTLS_MD5_C) +const mbedtls_md_info_t mbedtls_md5_info = { + "MD5", + MBEDTLS_MD_MD5, + 16, + 64, +}; +#endif + +#if defined(MBEDTLS_RIPEMD160_C) +const mbedtls_md_info_t mbedtls_ripemd160_info = { + "RIPEMD160", + MBEDTLS_MD_RIPEMD160, + 20, + 64, +}; +#endif + +#if defined(MBEDTLS_SHA1_C) +const mbedtls_md_info_t mbedtls_sha1_info = { + "SHA1", + MBEDTLS_MD_SHA1, + 20, + 64, +}; +#endif + +#if defined(MBEDTLS_SHA256_C) +const mbedtls_md_info_t mbedtls_sha224_info = { + "SHA224", + MBEDTLS_MD_SHA224, + 28, + 64, +}; + +const mbedtls_md_info_t mbedtls_sha256_info = { + "SHA256", + MBEDTLS_MD_SHA256, + 32, + 64, +}; +#endif + +#if defined(MBEDTLS_SHA512_C) +const mbedtls_md_info_t mbedtls_sha384_info = { + "SHA384", + MBEDTLS_MD_SHA384, + 48, + 128, +}; + +const mbedtls_md_info_t mbedtls_sha512_info = { + "SHA512", + MBEDTLS_MD_SHA512, + 64, + 128, +}; +#endif + /* * Reminder: update profiles in Mbed TLS's x509_crt.c when adding a new hash! */ @@ -185,7 +270,52 @@ void mbedtls_md_free( mbedtls_md_context_t *ctx ) return; if( ctx->md_ctx != NULL ) - ctx->md_info->ctx_free_func( ctx->md_ctx ); + { + switch( ctx->md_info->type ) + { +#if defined(MBEDTLS_MD2_C) + case MBEDTLS_MD_MD2: + mbedtls_md2_free( ctx->md_ctx ); + break; +#endif +#if defined(MBEDTLS_MD4_C) + case MBEDTLS_MD_MD4: + mbedtls_md4_free( ctx->md_ctx ); + break; +#endif +#if defined(MBEDTLS_MD5_C) + case MBEDTLS_MD_MD5: + mbedtls_md5_free( ctx->md_ctx ); + break; +#endif +#if defined(MBEDTLS_RIPEMD160_C) + case MBEDTLS_MD_RIPEMD160: + mbedtls_ripemd160_free( ctx->md_ctx ); + break; +#endif +#if defined(MBEDTLS_SHA1_C) + case MBEDTLS_MD_SHA1: + mbedtls_sha1_free( ctx->md_ctx ); + break; +#endif +#if defined(MBEDTLS_SHA256_C) + case MBEDTLS_MD_SHA224: + case MBEDTLS_MD_SHA256: + mbedtls_sha256_free( ctx->md_ctx ); + break; +#endif +#if defined(MBEDTLS_SHA512_C) + case MBEDTLS_MD_SHA384: + case MBEDTLS_MD_SHA512: + mbedtls_sha512_free( ctx->md_ctx ); + break; +#endif + default: + /* Shouldn't happen */ + break; + } + mbedtls_free( ctx->md_ctx ); + } if( ctx->hmac_ctx != NULL ) { @@ -207,7 +337,48 @@ int mbedtls_md_clone( mbedtls_md_context_t *dst, return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); } - dst->md_info->clone_func( dst->md_ctx, src->md_ctx ); + switch( src->md_info->type ) + { +#if defined(MBEDTLS_MD2_C) + case MBEDTLS_MD_MD2: + mbedtls_md2_clone( dst->md_ctx, src->md_ctx ); + break; +#endif +#if defined(MBEDTLS_MD4_C) + case MBEDTLS_MD_MD4: + mbedtls_md4_clone( dst->md_ctx, src->md_ctx ); + break; +#endif +#if defined(MBEDTLS_MD5_C) + case MBEDTLS_MD_MD5: + mbedtls_md5_clone( dst->md_ctx, src->md_ctx ); + break; +#endif +#if defined(MBEDTLS_RIPEMD160_C) + case MBEDTLS_MD_RIPEMD160: + mbedtls_ripemd160_clone( dst->md_ctx, src->md_ctx ); + break; +#endif +#if defined(MBEDTLS_SHA1_C) + case MBEDTLS_MD_SHA1: + mbedtls_sha1_clone( dst->md_ctx, src->md_ctx ); + break; +#endif +#if defined(MBEDTLS_SHA256_C) + case MBEDTLS_MD_SHA224: + case MBEDTLS_MD_SHA256: + mbedtls_sha256_clone( dst->md_ctx, src->md_ctx ); + break; +#endif +#if defined(MBEDTLS_SHA512_C) + case MBEDTLS_MD_SHA384: + case MBEDTLS_MD_SHA512: + mbedtls_sha512_clone( dst->md_ctx, src->md_ctx ); + break; +#endif + default: + return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); + } return( 0 ); } @@ -219,20 +390,69 @@ int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_ } #endif +#define ALLOC( type ) \ + do { \ + ctx->md_ctx = mbedtls_calloc( 1, sizeof( mbedtls_##type##_context ) ); \ + if( ctx->md_ctx == NULL ) \ + return( MBEDTLS_ERR_MD_ALLOC_FAILED ); \ + mbedtls_##type##_init( ctx->md_ctx ); \ + } \ + while( 0 ) + int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac ) { if( md_info == NULL || ctx == NULL ) return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL ) - return( MBEDTLS_ERR_MD_ALLOC_FAILED ); + switch( md_info->type ) + { +#if defined(MBEDTLS_MD2_C) + case MBEDTLS_MD_MD2: + ALLOC( md2 ); + break; +#endif +#if defined(MBEDTLS_MD4_C) + case MBEDTLS_MD_MD4: + ALLOC( md4 ); + break; +#endif +#if defined(MBEDTLS_MD5_C) + case MBEDTLS_MD_MD5: + ALLOC( md5 ); + break; +#endif +#if defined(MBEDTLS_RIPEMD160_C) + case MBEDTLS_MD_RIPEMD160: + ALLOC( ripemd160 ); + break; +#endif +#if defined(MBEDTLS_SHA1_C) + case MBEDTLS_MD_SHA1: + ALLOC( sha1 ); + break; +#endif +#if defined(MBEDTLS_SHA256_C) + case MBEDTLS_MD_SHA224: + case MBEDTLS_MD_SHA256: + ALLOC( sha256 ); + break; +#endif +#if defined(MBEDTLS_SHA512_C) + case MBEDTLS_MD_SHA384: + case MBEDTLS_MD_SHA512: + ALLOC( sha512 ); + break; +#endif + default: + return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); + } if( hmac != 0 ) { ctx->hmac_ctx = mbedtls_calloc( 2, md_info->block_size ); if( ctx->hmac_ctx == NULL ) { - md_info->ctx_free_func( ctx->md_ctx ); + mbedtls_md_free( ctx ); return( MBEDTLS_ERR_MD_ALLOC_FAILED ); } } @@ -241,13 +461,50 @@ int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_inf return( 0 ); } +#undef ALLOC int mbedtls_md_starts( mbedtls_md_context_t *ctx ) { if( ctx == NULL || ctx->md_info == NULL ) return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - return( ctx->md_info->starts_func( ctx->md_ctx ) ); + switch( ctx->md_info->type ) + { +#if defined(MBEDTLS_MD2_C) + case MBEDTLS_MD_MD2: + return( mbedtls_md2_starts_ret( ctx->md_ctx ) ); +#endif +#if defined(MBEDTLS_MD4_C) + case MBEDTLS_MD_MD4: + return( mbedtls_md4_starts_ret( ctx->md_ctx ) ); +#endif +#if defined(MBEDTLS_MD5_C) + case MBEDTLS_MD_MD5: + return( mbedtls_md5_starts_ret( ctx->md_ctx ) ); +#endif +#if defined(MBEDTLS_RIPEMD160_C) + case MBEDTLS_MD_RIPEMD160: + return( mbedtls_ripemd160_starts_ret( ctx->md_ctx ) ); +#endif +#if defined(MBEDTLS_SHA1_C) + case MBEDTLS_MD_SHA1: + return( mbedtls_sha1_starts_ret( ctx->md_ctx ) ); +#endif +#if defined(MBEDTLS_SHA256_C) + case MBEDTLS_MD_SHA224: + return( mbedtls_sha256_starts_ret( ctx->md_ctx, 1 ) ); + case MBEDTLS_MD_SHA256: + return( mbedtls_sha256_starts_ret( ctx->md_ctx, 0 ) ); +#endif +#if defined(MBEDTLS_SHA512_C) + case MBEDTLS_MD_SHA384: + return( mbedtls_sha512_starts_ret( ctx->md_ctx, 1 ) ); + case MBEDTLS_MD_SHA512: + return( mbedtls_sha512_starts_ret( ctx->md_ctx, 0 ) ); +#endif + default: + return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); + } } int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ) @@ -255,7 +512,43 @@ int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, si if( ctx == NULL || ctx->md_info == NULL ) return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) ); + switch( ctx->md_info->type ) + { +#if defined(MBEDTLS_MD2_C) + case MBEDTLS_MD_MD2: + return( mbedtls_md2_update_ret( ctx->md_ctx, input, ilen ) ); +#endif +#if defined(MBEDTLS_MD4_C) + case MBEDTLS_MD_MD4: + return( mbedtls_md4_update_ret( ctx->md_ctx, input, ilen ) ); +#endif +#if defined(MBEDTLS_MD5_C) + case MBEDTLS_MD_MD5: + return( mbedtls_md5_update_ret( ctx->md_ctx, input, ilen ) ); +#endif +#if defined(MBEDTLS_RIPEMD160_C) + case MBEDTLS_MD_RIPEMD160: + return( mbedtls_ripemd160_update_ret( ctx->md_ctx, input, ilen ) ); +#endif +#if defined(MBEDTLS_SHA1_C) + case MBEDTLS_MD_SHA1: + return( mbedtls_sha1_update_ret( ctx->md_ctx, input, ilen ) ); +#endif +#if defined(MBEDTLS_SHA256_C) + case MBEDTLS_MD_SHA224: + return( mbedtls_sha256_update_ret( ctx->md_ctx, input, ilen ) ); + case MBEDTLS_MD_SHA256: + return( mbedtls_sha256_update_ret( ctx->md_ctx, input, ilen ) ); +#endif +#if defined(MBEDTLS_SHA512_C) + case MBEDTLS_MD_SHA384: + return( mbedtls_sha512_update_ret( ctx->md_ctx, input, ilen ) ); + case MBEDTLS_MD_SHA512: + return( mbedtls_sha512_update_ret( ctx->md_ctx, input, ilen ) ); +#endif + default: + return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); + } } int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output ) @@ -263,7 +556,43 @@ int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output ) if( ctx == NULL || ctx->md_info == NULL ) return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - return( ctx->md_info->finish_func( ctx->md_ctx, output ) ); + switch( ctx->md_info->type ) + { +#if defined(MBEDTLS_MD2_C) + case MBEDTLS_MD_MD2: + return( mbedtls_md2_finish_ret( ctx->md_ctx, output ) ); +#endif +#if defined(MBEDTLS_MD4_C) + case MBEDTLS_MD_MD4: + return( mbedtls_md4_finish_ret( ctx->md_ctx, output ) ); +#endif +#if defined(MBEDTLS_MD5_C) + case MBEDTLS_MD_MD5: + return( mbedtls_md5_finish_ret( ctx->md_ctx, output ) ); +#endif +#if defined(MBEDTLS_RIPEMD160_C) + case MBEDTLS_MD_RIPEMD160: + return( mbedtls_ripemd160_finish_ret( ctx->md_ctx, output ) ); +#endif +#if defined(MBEDTLS_SHA1_C) + case MBEDTLS_MD_SHA1: + return( mbedtls_sha1_finish_ret( ctx->md_ctx, output ) ); +#endif +#if defined(MBEDTLS_SHA256_C) + case MBEDTLS_MD_SHA224: + return( mbedtls_sha256_finish_ret( ctx->md_ctx, output ) ); + case MBEDTLS_MD_SHA256: + return( mbedtls_sha256_finish_ret( ctx->md_ctx, output ) ); +#endif +#if defined(MBEDTLS_SHA512_C) + case MBEDTLS_MD_SHA384: + return( mbedtls_sha512_finish_ret( ctx->md_ctx, output ) ); + case MBEDTLS_MD_SHA512: + return( mbedtls_sha512_finish_ret( ctx->md_ctx, output ) ); +#endif + default: + return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); + } } int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, @@ -272,7 +601,43 @@ int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, si if( md_info == NULL ) return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - return( md_info->digest_func( input, ilen, output ) ); + switch( md_info->type ) + { +#if defined(MBEDTLS_MD2_C) + case MBEDTLS_MD_MD2: + return( mbedtls_md2_ret( input, ilen, output ) ); +#endif +#if defined(MBEDTLS_MD4_C) + case MBEDTLS_MD_MD4: + return( mbedtls_md4_ret( input, ilen, output ) ); +#endif +#if defined(MBEDTLS_MD5_C) + case MBEDTLS_MD_MD5: + return( mbedtls_md5_ret( input, ilen, output ) ); +#endif +#if defined(MBEDTLS_RIPEMD160_C) + case MBEDTLS_MD_RIPEMD160: + return( mbedtls_ripemd160_ret( input, ilen, output ) ); +#endif +#if defined(MBEDTLS_SHA1_C) + case MBEDTLS_MD_SHA1: + return( mbedtls_sha1_ret( input, ilen, output ) ); +#endif +#if defined(MBEDTLS_SHA256_C) + case MBEDTLS_MD_SHA224: + return( mbedtls_sha256_ret( input, ilen, output, 1 ) ); + case MBEDTLS_MD_SHA256: + return( mbedtls_sha256_ret( input, ilen, output, 0 ) ); +#endif +#if defined(MBEDTLS_SHA512_C) + case MBEDTLS_MD_SHA384: + return( mbedtls_sha512_ret( input, ilen, output, 1 ) ); + case MBEDTLS_MD_SHA512: + return( mbedtls_sha512_ret( input, ilen, output, 0 ) ); +#endif + default: + return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); + } } #if defined(MBEDTLS_FS_IO) @@ -295,17 +660,17 @@ int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigne if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 ) goto cleanup; - if( ( ret = md_info->starts_func( ctx.md_ctx ) ) != 0 ) + if( ( ret = mbedtls_md_starts( &ctx ) ) != 0 ) goto cleanup; while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) - if( ( ret = md_info->update_func( ctx.md_ctx, buf, n ) ) != 0 ) + if( ( ret = mbedtls_md_update( &ctx, buf, n ) ) != 0 ) goto cleanup; if( ferror( f ) != 0 ) ret = MBEDTLS_ERR_MD_FILE_IO_ERROR; else - ret = md_info->finish_func( ctx.md_ctx, output ); + ret = mbedtls_md_finish( &ctx, output ); cleanup: mbedtls_platform_zeroize( buf, sizeof( buf ) ); @@ -328,11 +693,11 @@ int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, if( keylen > (size_t) ctx->md_info->block_size ) { - if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) + if( ( ret = mbedtls_md_starts( ctx ) ) != 0 ) goto cleanup; - if( ( ret = ctx->md_info->update_func( ctx->md_ctx, key, keylen ) ) != 0 ) + if( ( ret = mbedtls_md_update( ctx, key, keylen ) ) != 0 ) goto cleanup; - if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, sum ) ) != 0 ) + if( ( ret = mbedtls_md_finish( ctx, sum ) ) != 0 ) goto cleanup; keylen = ctx->md_info->size; @@ -351,10 +716,10 @@ int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, opad[i] = (unsigned char)( opad[i] ^ key[i] ); } - if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) + if( ( ret = mbedtls_md_starts( ctx ) ) != 0 ) goto cleanup; - if( ( ret = ctx->md_info->update_func( ctx->md_ctx, ipad, - ctx->md_info->block_size ) ) != 0 ) + if( ( ret = mbedtls_md_update( ctx, ipad, + ctx->md_info->block_size ) ) != 0 ) goto cleanup; cleanup: @@ -368,7 +733,7 @@ int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *inpu if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) ); + return( mbedtls_md_update( ctx, input, ilen ) ); } int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output ) @@ -382,17 +747,17 @@ int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output ) opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; - if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, tmp ) ) != 0 ) + if( ( ret = mbedtls_md_finish( ctx, tmp ) ) != 0 ) return( ret ); - if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) + if( ( ret = mbedtls_md_starts( ctx ) ) != 0 ) return( ret ); - if( ( ret = ctx->md_info->update_func( ctx->md_ctx, opad, - ctx->md_info->block_size ) ) != 0 ) + if( ( ret = mbedtls_md_update( ctx, opad, + ctx->md_info->block_size ) ) != 0 ) return( ret ); - if( ( ret = ctx->md_info->update_func( ctx->md_ctx, tmp, - ctx->md_info->size ) ) != 0 ) + if( ( ret = mbedtls_md_update( ctx, tmp, + ctx->md_info->size ) ) != 0 ) return( ret ); - return( ctx->md_info->finish_func( ctx->md_ctx, output ) ); + return( mbedtls_md_finish( ctx, output ) ); } int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx ) @@ -405,10 +770,9 @@ int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx ) ipad = (unsigned char *) ctx->hmac_ctx; - if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) + if( ( ret = mbedtls_md_starts( ctx ) ) != 0 ) return( ret ); - return( ctx->md_info->update_func( ctx->md_ctx, ipad, - ctx->md_info->block_size ) ); + return( mbedtls_md_update( ctx, ipad, ctx->md_info->block_size ) ); } int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, @@ -445,7 +809,43 @@ int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data ) if( ctx == NULL || ctx->md_info == NULL ) return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - return( ctx->md_info->process_func( ctx->md_ctx, data ) ); + switch( ctx->md_info->type ) + { +#if defined(MBEDTLS_MD2_C) + case MBEDTLS_MD_MD2: + return( mbedtls_internal_md2_process( ctx->md_ctx ) ); +#endif +#if defined(MBEDTLS_MD4_C) + case MBEDTLS_MD_MD4: + return( mbedtls_internal_md4_process( ctx->md_ctx, data ) ); +#endif +#if defined(MBEDTLS_MD5_C) + case MBEDTLS_MD_MD5: + return( mbedtls_internal_md5_process( ctx->md_ctx, data ) ); +#endif +#if defined(MBEDTLS_RIPEMD160_C) + case MBEDTLS_MD_RIPEMD160: + return( mbedtls_internal_ripemd160_process( ctx->md_ctx, data ) ); +#endif +#if defined(MBEDTLS_SHA1_C) + case MBEDTLS_MD_SHA1: + return( mbedtls_internal_sha1_process( ctx->md_ctx, data ) ); +#endif +#if defined(MBEDTLS_SHA256_C) + case MBEDTLS_MD_SHA224: + return( mbedtls_internal_sha256_process( ctx->md_ctx, data ) ); + case MBEDTLS_MD_SHA256: + return( mbedtls_internal_sha256_process( ctx->md_ctx, data ) ); +#endif +#if defined(MBEDTLS_SHA512_C) + case MBEDTLS_MD_SHA384: + return( mbedtls_internal_sha512_process( ctx->md_ctx, data ) ); + case MBEDTLS_MD_SHA512: + return( mbedtls_internal_sha512_process( ctx->md_ctx, data ) ); +#endif + default: + return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); + } } unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info ) diff --git a/features/mbedtls/mbed-crypto/src/md_wrap.c b/features/mbedtls/mbed-crypto/src/md_wrap.c deleted file mode 100644 index 32f0871976..0000000000 --- a/features/mbedtls/mbed-crypto/src/md_wrap.c +++ /dev/null @@ -1,586 +0,0 @@ -/** - * \file md_wrap.c - * - * \brief Generic message digest wrapper for mbed TLS - * - * \author Adriaan de Jong - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_MD_C) - -#include "mbedtls/md_internal.h" - -#if defined(MBEDTLS_MD2_C) -#include "mbedtls/md2.h" -#endif - -#if defined(MBEDTLS_MD4_C) -#include "mbedtls/md4.h" -#endif - -#if defined(MBEDTLS_MD5_C) -#include "mbedtls/md5.h" -#endif - -#if defined(MBEDTLS_RIPEMD160_C) -#include "mbedtls/ripemd160.h" -#endif - -#if defined(MBEDTLS_SHA1_C) -#include "mbedtls/sha1.h" -#endif - -#if defined(MBEDTLS_SHA256_C) -#include "mbedtls/sha256.h" -#endif - -#if defined(MBEDTLS_SHA512_C) -#include "mbedtls/sha512.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#if defined(MBEDTLS_MD2_C) - -static int md2_starts_wrap( void *ctx ) -{ - return( mbedtls_md2_starts_ret( (mbedtls_md2_context *) ctx ) ); -} - -static int md2_update_wrap( void *ctx, const unsigned char *input, - size_t ilen ) -{ - return( mbedtls_md2_update_ret( (mbedtls_md2_context *) ctx, input, ilen ) ); -} - -static int md2_finish_wrap( void *ctx, unsigned char *output ) -{ - return( mbedtls_md2_finish_ret( (mbedtls_md2_context *) ctx, output ) ); -} - -static void *md2_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md2_context ) ); - - if( ctx != NULL ) - mbedtls_md2_init( (mbedtls_md2_context *) ctx ); - - return( ctx ); -} - -static void md2_ctx_free( void *ctx ) -{ - mbedtls_md2_free( (mbedtls_md2_context *) ctx ); - mbedtls_free( ctx ); -} - -static void md2_clone_wrap( void *dst, const void *src ) -{ - mbedtls_md2_clone( (mbedtls_md2_context *) dst, - (const mbedtls_md2_context *) src ); -} - -static int md2_process_wrap( void *ctx, const unsigned char *data ) -{ - ((void) data); - - return( mbedtls_internal_md2_process( (mbedtls_md2_context *) ctx ) ); -} - -const mbedtls_md_info_t mbedtls_md2_info = { - MBEDTLS_MD_MD2, - "MD2", - 16, - 16, - md2_starts_wrap, - md2_update_wrap, - md2_finish_wrap, - mbedtls_md2_ret, - md2_ctx_alloc, - md2_ctx_free, - md2_clone_wrap, - md2_process_wrap, -}; - -#endif /* MBEDTLS_MD2_C */ - -#if defined(MBEDTLS_MD4_C) - -static int md4_starts_wrap( void *ctx ) -{ - return( mbedtls_md4_starts_ret( (mbedtls_md4_context *) ctx ) ); -} - -static int md4_update_wrap( void *ctx, const unsigned char *input, - size_t ilen ) -{ - return( mbedtls_md4_update_ret( (mbedtls_md4_context *) ctx, input, ilen ) ); -} - -static int md4_finish_wrap( void *ctx, unsigned char *output ) -{ - return( mbedtls_md4_finish_ret( (mbedtls_md4_context *) ctx, output ) ); -} - -static void *md4_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md4_context ) ); - - if( ctx != NULL ) - mbedtls_md4_init( (mbedtls_md4_context *) ctx ); - - return( ctx ); -} - -static void md4_ctx_free( void *ctx ) -{ - mbedtls_md4_free( (mbedtls_md4_context *) ctx ); - mbedtls_free( ctx ); -} - -static void md4_clone_wrap( void *dst, const void *src ) -{ - mbedtls_md4_clone( (mbedtls_md4_context *) dst, - (const mbedtls_md4_context *) src ); -} - -static int md4_process_wrap( void *ctx, const unsigned char *data ) -{ - return( mbedtls_internal_md4_process( (mbedtls_md4_context *) ctx, data ) ); -} - -const mbedtls_md_info_t mbedtls_md4_info = { - MBEDTLS_MD_MD4, - "MD4", - 16, - 64, - md4_starts_wrap, - md4_update_wrap, - md4_finish_wrap, - mbedtls_md4_ret, - md4_ctx_alloc, - md4_ctx_free, - md4_clone_wrap, - md4_process_wrap, -}; - -#endif /* MBEDTLS_MD4_C */ - -#if defined(MBEDTLS_MD5_C) - -static int md5_starts_wrap( void *ctx ) -{ - return( mbedtls_md5_starts_ret( (mbedtls_md5_context *) ctx ) ); -} - -static int md5_update_wrap( void *ctx, const unsigned char *input, - size_t ilen ) -{ - return( mbedtls_md5_update_ret( (mbedtls_md5_context *) ctx, input, ilen ) ); -} - -static int md5_finish_wrap( void *ctx, unsigned char *output ) -{ - return( mbedtls_md5_finish_ret( (mbedtls_md5_context *) ctx, output ) ); -} - -static void *md5_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md5_context ) ); - - if( ctx != NULL ) - mbedtls_md5_init( (mbedtls_md5_context *) ctx ); - - return( ctx ); -} - -static void md5_ctx_free( void *ctx ) -{ - mbedtls_md5_free( (mbedtls_md5_context *) ctx ); - mbedtls_free( ctx ); -} - -static void md5_clone_wrap( void *dst, const void *src ) -{ - mbedtls_md5_clone( (mbedtls_md5_context *) dst, - (const mbedtls_md5_context *) src ); -} - -static int md5_process_wrap( void *ctx, const unsigned char *data ) -{ - return( mbedtls_internal_md5_process( (mbedtls_md5_context *) ctx, data ) ); -} - -const mbedtls_md_info_t mbedtls_md5_info = { - MBEDTLS_MD_MD5, - "MD5", - 16, - 64, - md5_starts_wrap, - md5_update_wrap, - md5_finish_wrap, - mbedtls_md5_ret, - md5_ctx_alloc, - md5_ctx_free, - md5_clone_wrap, - md5_process_wrap, -}; - -#endif /* MBEDTLS_MD5_C */ - -#if defined(MBEDTLS_RIPEMD160_C) - -static int ripemd160_starts_wrap( void *ctx ) -{ - return( mbedtls_ripemd160_starts_ret( (mbedtls_ripemd160_context *) ctx ) ); -} - -static int ripemd160_update_wrap( void *ctx, const unsigned char *input, - size_t ilen ) -{ - return( mbedtls_ripemd160_update_ret( (mbedtls_ripemd160_context *) ctx, - input, ilen ) ); -} - -static int ripemd160_finish_wrap( void *ctx, unsigned char *output ) -{ - return( mbedtls_ripemd160_finish_ret( (mbedtls_ripemd160_context *) ctx, - output ) ); -} - -static void *ripemd160_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ripemd160_context ) ); - - if( ctx != NULL ) - mbedtls_ripemd160_init( (mbedtls_ripemd160_context *) ctx ); - - return( ctx ); -} - -static void ripemd160_ctx_free( void *ctx ) -{ - mbedtls_ripemd160_free( (mbedtls_ripemd160_context *) ctx ); - mbedtls_free( ctx ); -} - -static void ripemd160_clone_wrap( void *dst, const void *src ) -{ - mbedtls_ripemd160_clone( (mbedtls_ripemd160_context *) dst, - (const mbedtls_ripemd160_context *) src ); -} - -static int ripemd160_process_wrap( void *ctx, const unsigned char *data ) -{ - return( mbedtls_internal_ripemd160_process( - (mbedtls_ripemd160_context *) ctx, data ) ); -} - -const mbedtls_md_info_t mbedtls_ripemd160_info = { - MBEDTLS_MD_RIPEMD160, - "RIPEMD160", - 20, - 64, - ripemd160_starts_wrap, - ripemd160_update_wrap, - ripemd160_finish_wrap, - mbedtls_ripemd160_ret, - ripemd160_ctx_alloc, - ripemd160_ctx_free, - ripemd160_clone_wrap, - ripemd160_process_wrap, -}; - -#endif /* MBEDTLS_RIPEMD160_C */ - -#if defined(MBEDTLS_SHA1_C) - -static int sha1_starts_wrap( void *ctx ) -{ - return( mbedtls_sha1_starts_ret( (mbedtls_sha1_context *) ctx ) ); -} - -static int sha1_update_wrap( void *ctx, const unsigned char *input, - size_t ilen ) -{ - return( mbedtls_sha1_update_ret( (mbedtls_sha1_context *) ctx, - input, ilen ) ); -} - -static int sha1_finish_wrap( void *ctx, unsigned char *output ) -{ - return( mbedtls_sha1_finish_ret( (mbedtls_sha1_context *) ctx, output ) ); -} - -static void *sha1_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha1_context ) ); - - if( ctx != NULL ) - mbedtls_sha1_init( (mbedtls_sha1_context *) ctx ); - - return( ctx ); -} - -static void sha1_clone_wrap( void *dst, const void *src ) -{ - mbedtls_sha1_clone( (mbedtls_sha1_context *) dst, - (const mbedtls_sha1_context *) src ); -} - -static void sha1_ctx_free( void *ctx ) -{ - mbedtls_sha1_free( (mbedtls_sha1_context *) ctx ); - mbedtls_free( ctx ); -} - -static int sha1_process_wrap( void *ctx, const unsigned char *data ) -{ - return( mbedtls_internal_sha1_process( (mbedtls_sha1_context *) ctx, - data ) ); -} - -const mbedtls_md_info_t mbedtls_sha1_info = { - MBEDTLS_MD_SHA1, - "SHA1", - 20, - 64, - sha1_starts_wrap, - sha1_update_wrap, - sha1_finish_wrap, - mbedtls_sha1_ret, - sha1_ctx_alloc, - sha1_ctx_free, - sha1_clone_wrap, - sha1_process_wrap, -}; - -#endif /* MBEDTLS_SHA1_C */ - -/* - * Wrappers for generic message digests - */ -#if defined(MBEDTLS_SHA256_C) - -static int sha224_starts_wrap( void *ctx ) -{ - return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 1 ) ); -} - -static int sha224_update_wrap( void *ctx, const unsigned char *input, - size_t ilen ) -{ - return( mbedtls_sha256_update_ret( (mbedtls_sha256_context *) ctx, - input, ilen ) ); -} - -static int sha224_finish_wrap( void *ctx, unsigned char *output ) -{ - return( mbedtls_sha256_finish_ret( (mbedtls_sha256_context *) ctx, - output ) ); -} - -static int sha224_wrap( const unsigned char *input, size_t ilen, - unsigned char *output ) -{ - return( mbedtls_sha256_ret( input, ilen, output, 1 ) ); -} - -static void *sha224_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha256_context ) ); - - if( ctx != NULL ) - mbedtls_sha256_init( (mbedtls_sha256_context *) ctx ); - - return( ctx ); -} - -static void sha224_ctx_free( void *ctx ) -{ - mbedtls_sha256_free( (mbedtls_sha256_context *) ctx ); - mbedtls_free( ctx ); -} - -static void sha224_clone_wrap( void *dst, const void *src ) -{ - mbedtls_sha256_clone( (mbedtls_sha256_context *) dst, - (const mbedtls_sha256_context *) src ); -} - -static int sha224_process_wrap( void *ctx, const unsigned char *data ) -{ - return( mbedtls_internal_sha256_process( (mbedtls_sha256_context *) ctx, - data ) ); -} - -const mbedtls_md_info_t mbedtls_sha224_info = { - MBEDTLS_MD_SHA224, - "SHA224", - 28, - 64, - sha224_starts_wrap, - sha224_update_wrap, - sha224_finish_wrap, - sha224_wrap, - sha224_ctx_alloc, - sha224_ctx_free, - sha224_clone_wrap, - sha224_process_wrap, -}; - -static int sha256_starts_wrap( void *ctx ) -{ - return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 0 ) ); -} - -static int sha256_wrap( const unsigned char *input, size_t ilen, - unsigned char *output ) -{ - return( mbedtls_sha256_ret( input, ilen, output, 0 ) ); -} - -const mbedtls_md_info_t mbedtls_sha256_info = { - MBEDTLS_MD_SHA256, - "SHA256", - 32, - 64, - sha256_starts_wrap, - sha224_update_wrap, - sha224_finish_wrap, - sha256_wrap, - sha224_ctx_alloc, - sha224_ctx_free, - sha224_clone_wrap, - sha224_process_wrap, -}; - -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - -static int sha384_starts_wrap( void *ctx ) -{ - return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 1 ) ); -} - -static int sha384_update_wrap( void *ctx, const unsigned char *input, - size_t ilen ) -{ - return( mbedtls_sha512_update_ret( (mbedtls_sha512_context *) ctx, - input, ilen ) ); -} - -static int sha384_finish_wrap( void *ctx, unsigned char *output ) -{ - return( mbedtls_sha512_finish_ret( (mbedtls_sha512_context *) ctx, - output ) ); -} - -static int sha384_wrap( const unsigned char *input, size_t ilen, - unsigned char *output ) -{ - return( mbedtls_sha512_ret( input, ilen, output, 1 ) ); -} - -static void *sha384_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha512_context ) ); - - if( ctx != NULL ) - mbedtls_sha512_init( (mbedtls_sha512_context *) ctx ); - - return( ctx ); -} - -static void sha384_ctx_free( void *ctx ) -{ - mbedtls_sha512_free( (mbedtls_sha512_context *) ctx ); - mbedtls_free( ctx ); -} - -static void sha384_clone_wrap( void *dst, const void *src ) -{ - mbedtls_sha512_clone( (mbedtls_sha512_context *) dst, - (const mbedtls_sha512_context *) src ); -} - -static int sha384_process_wrap( void *ctx, const unsigned char *data ) -{ - return( mbedtls_internal_sha512_process( (mbedtls_sha512_context *) ctx, - data ) ); -} - -const mbedtls_md_info_t mbedtls_sha384_info = { - MBEDTLS_MD_SHA384, - "SHA384", - 48, - 128, - sha384_starts_wrap, - sha384_update_wrap, - sha384_finish_wrap, - sha384_wrap, - sha384_ctx_alloc, - sha384_ctx_free, - sha384_clone_wrap, - sha384_process_wrap, -}; - -static int sha512_starts_wrap( void *ctx ) -{ - return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 0 ) ); -} - -static int sha512_wrap( const unsigned char *input, size_t ilen, - unsigned char *output ) -{ - return( mbedtls_sha512_ret( input, ilen, output, 0 ) ); -} - -const mbedtls_md_info_t mbedtls_sha512_info = { - MBEDTLS_MD_SHA512, - "SHA512", - 64, - 128, - sha512_starts_wrap, - sha384_update_wrap, - sha384_finish_wrap, - sha512_wrap, - sha384_ctx_alloc, - sha384_ctx_free, - sha384_clone_wrap, - sha384_process_wrap, -}; - -#endif /* MBEDTLS_SHA512_C */ - -#endif /* MBEDTLS_MD_C */ diff --git a/features/mbedtls/mbed-crypto/src/pkcs5.c b/features/mbedtls/mbed-crypto/src/pkcs5.c index e7d805c2c6..3d29fd7e59 100644 --- a/features/mbedtls/mbed-crypto/src/pkcs5.c +++ b/features/mbedtls/mbed-crypto/src/pkcs5.c @@ -243,13 +243,12 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, return( MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA ); #endif + if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 ) + return( ret ); while( key_length ) { // U1 ends up in work // - if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 ) - return( ret ); - if( ( ret = mbedtls_md_hmac_update( ctx, salt, slen ) ) != 0 ) return( ret ); @@ -259,21 +258,24 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, if( ( ret = mbedtls_md_hmac_finish( ctx, work ) ) != 0 ) return( ret ); + if( ( ret = mbedtls_md_hmac_reset( ctx ) ) != 0 ) + return( ret ); + memcpy( md1, work, md_size ); for( i = 1; i < iteration_count; i++ ) { // U2 ends up in md1 // - if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 ) - return( ret ); - if( ( ret = mbedtls_md_hmac_update( ctx, md1, md_size ) ) != 0 ) return( ret ); if( ( ret = mbedtls_md_hmac_finish( ctx, md1 ) ) != 0 ) return( ret ); + if( ( ret = mbedtls_md_hmac_reset( ctx ) ) != 0 ) + return( ret ); + // U1 xor U2 // for( j = 0; j < md_size; j++ )