crypto: Update to Mbed Crypto 1.0.0d1

pull/9529/head
Jaeden Amero 2019-01-22 17:53:11 +00:00 committed by Oren Cohen
parent 4a1584696c
commit c3223072dc
23 changed files with 4165 additions and 2985 deletions

View File

@ -1 +1 @@
mbedcrypto-0.1.0b2
mbedcrypto-1.0.0d1

View File

@ -29,7 +29,7 @@
# Set the Mbed Crypto release to import (this can/should be edited before
# import)
CRYPTO_RELEASE ?= mbedcrypto-1.0.0d0
CRYPTO_RELEASE ?= mbedcrypto-1.0.0d1
CRYPTO_REPO_URL ?= git@github.com:ARMmbed/mbed-crypto.git
# Translate between Mbed Crypto namespace and Mbed OS namespace

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,796 @@
/**
* \file psa/crypto_accel_driver.h
* \brief PSA cryptography accelerator driver module
*
* This header declares types and function signatures for cryptography
* drivers that access key material directly. This is meant for
* on-chip cryptography accelerators.
*
* This file is part of the PSA Crypto Driver Model, containing functions for
* driver developers to implement to enable hardware to be called in a
* standardized way by a PSA Cryptographic API implementation. The functions
* comprising the driver model, which driver authors implement, are not
* intended to be called by application developers.
*/
/*
* Copyright (C) 2018, 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.
*/
#ifndef PSA_CRYPTO_ACCEL_DRIVER_H
#define PSA_CRYPTO_ACCEL_DRIVER_H
#include "crypto_driver_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup driver_digest Message Digests
*
* Generation and authentication of Message Digests (aka hashes) must be done
* in parts using the following sequence:
* - `psa_drv_hash_setup_t`
* - `psa_drv_hash_update_t`
* - ...
* - `psa_drv_hash_finish_t`
*
* If a previously started Message Digest operation needs to be terminated
* before the `psa_drv_hash_finish_t` operation is complete, it should be aborted
* by the `psa_drv_hash_abort_t`. Failure to do so may result in allocated
* resources not being freed or in other undefined behavior.
*/
/**@{*/
/** \brief The hardware-specific hash context structure
*
* The contents of this structure are implementation dependent and are
* therefore not described here
*/
typedef struct psa_drv_hash_context_s psa_drv_hash_context_t;
/** \brief The function prototype for the start operation of a hash (message
* digest) operation
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_hash_<ALGO>_setup
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the underlying hash function
*
* \param[in,out] p_context A structure that will contain the
* hardware-specific hash context
*
* \retval PSA_SUCCESS Success.
*/
typedef psa_status_t (*psa_drv_hash_setup_t)(psa_drv_hash_context_t *p_context);
/** \brief The function prototype for the update operation of a hash (message
* digest) operation
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_hash_<ALGO>_update
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the underlying algorithm
*
* \param[in,out] p_context A hardware-specific structure for the
* previously-established hash operation to be
* continued
* \param[in] p_input A buffer containing the message to be appended
* to the hash operation
* \param[in] input_length The size in bytes of the input message buffer
*/
typedef psa_status_t (*psa_drv_hash_update_t)(psa_drv_hash_context_t *p_context,
const uint8_t *p_input,
size_t input_length);
/** \brief The prototype for the finish operation of a hash (message digest)
* operation
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_hash_<ALGO>_finish
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the underlying algorithm
*
* \param[in,out] p_context A hardware-specific structure for the
* previously started hash operation to be
* fiinished
* \param[out] p_output A buffer where the generated digest will be
* placed
* \param[in] output_size The size in bytes of the buffer that has been
* allocated for the `p_output` buffer
* \param[out] p_output_length The number of bytes placed in `p_output` after
* success
*
* \retval PSA_SUCCESS
* Success.
*/
typedef psa_status_t (*psa_drv_hash_finish_t)(psa_drv_hash_context_t *p_context,
uint8_t *p_output,
size_t output_size,
size_t *p_output_length);
/** \brief The function prototype for the abort operation of a hash (message
* digest) operation
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_hash_<ALGO>_abort
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the underlying algorithm
*
* \param[in,out] p_context A hardware-specific structure for the previously
* started hash operation to be aborted
*/
typedef void (*psa_drv_hash_abort_t)(psa_drv_hash_context_t *p_context);
/**@}*/
/** \defgroup transparent_mac Transparent Message Authentication Code
* Generation and authentication of Message Authentication Codes (MACs) using
* transparent keys can be done either as a single function call (via the
* `psa_drv_mac_transparent_generate_t` or `psa_drv_mac_transparent_verify_t`
* functions), or in parts using the following sequence:
* - `psa_drv_mac_transparent_setup_t`
* - `psa_drv_mac_transparent_update_t`
* - `psa_drv_mac_transparent_update_t`
* - ...
* - `psa_drv_mac_transparent_finish_t` or `psa_drv_mac_transparent_finish_verify_t`
*
* If a previously started Transparent MAC operation needs to be terminated, it
* should be done so by the `psa_drv_mac_transparent_abort_t`. Failure to do so may
* result in allocated resources not being freed or in other undefined
* behavior.
*
*/
/**@{*/
/** \brief The hardware-specific transparent-key MAC context structure
*
* The contents of this structure are implementation dependent and are
* therefore not described here.
*/
typedef struct psa_drv_mac_transparent_context_s psa_drv_mac_transparent_context_t;
/** \brief The function prototype for the setup operation of a
* transparent-key MAC operation
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_mac_transparent_<ALGO>_<MAC_VARIANT>_setup
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the underlying primitive, and `MAC_VARIANT`
* is the specific variant of a MAC operation (such as HMAC or CMAC)
*
* \param[in,out] p_context A structure that will contain the
* hardware-specific MAC context
* \param[in] p_key A buffer containing the cleartext key material
* to be used in the operation
* \param[in] key_length The size in bytes of the key material
*
* \retval PSA_SUCCESS
* Success.
*/
typedef psa_status_t (*psa_drv_mac_transparent_setup_t)(psa_drv_mac_transparent_context_t *p_context,
const uint8_t *p_key,
size_t key_length);
/** \brief The function prototype for the update operation of a
* transparent-key MAC operation
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_mac_transparent_<ALGO>_<MAC_VARIANT>_update
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT`
* is the specific variant of a MAC operation (such as HMAC or CMAC)
*
* \param[in,out] p_context A hardware-specific structure for the
* previously-established MAC operation to be
* continued
* \param[in] p_input A buffer containing the message to be appended
* to the MAC operation
* \param[in] input_length The size in bytes of the input message buffer
*/
typedef psa_status_t (*psa_drv_mac_transparent_update_t)(psa_drv_mac_transparent_context_t *p_context,
const uint8_t *p_input,
size_t input_length);
/** \brief The function prototype for the finish operation of a
* transparent-key MAC operation
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_mac_transparent_<ALGO>_<MAC_VARIANT>_finish
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is
* the specific variant of a MAC operation (such as HMAC or CMAC)
*
* \param[in,out] p_context A hardware-specific structure for the
* previously started MAC operation to be
* finished
* \param[out] p_mac A buffer where the generated MAC will be placed
* \param[in] mac_length The size in bytes of the buffer that has been
* allocated for the `p_mac` buffer
*
* \retval PSA_SUCCESS
* Success.
*/
typedef psa_status_t (*psa_drv_mac_transparent_finish_t)(psa_drv_mac_transparent_context_t *p_context,
uint8_t *p_mac,
size_t mac_length);
/** \brief The function prototype for the finish and verify operation of a
* transparent-key MAC operation
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_mac_transparent_<ALGO>_<MAC_VARIANT>_finish_verify
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is
* the specific variant of a MAC operation (such as HMAC or CMAC)
*
* \param[in,out] p_context A hardware-specific structure for the
* previously started MAC operation to be
* verified and finished
* \param[in] p_mac A buffer containing the MAC that will be used
* for verification
* \param[in] mac_length The size in bytes of the data in the `p_mac`
* buffer
*
* \retval PSA_SUCCESS
* The operation completed successfully and the comparison matched
*/
typedef psa_status_t (*psa_drv_mac_transparent_finish_verify_t)(psa_drv_mac_transparent_context_t *p_context,
const uint8_t *p_mac,
size_t mac_length);
/** \brief The function prototype for the abort operation for a previously
* started transparent-key MAC operation
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_mac_transparent_<ALGO>_<MAC_VARIANT>_abort
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is
* the specific variant of a MAC operation (such as HMAC or CMAC)
*
* \param[in,out] p_context A hardware-specific structure for the
* previously started MAC operation to be
* aborted
*
*/
typedef psa_status_t (*psa_drv_mac_transparent_abort_t)(psa_drv_mac_transparent_context_t *p_context);
/** \brief The function prototype for a one-shot operation of a transparent-key
* MAC operation
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_mac_transparent_<ALGO>_<MAC_VARIANT>
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is
* the specific variant of a MAC operation (such as HMAC or CMAC)
*
* \param[in] p_input A buffer containing the data to be MACed
* \param[in] input_length The length in bytes of the `p_input` data
* \param[in] p_key A buffer containing the key material to be used
* for the MAC operation
* \param[in] key_length The length in bytes of the `p_key` data
* \param[in] alg The algorithm to be performed
* \param[out] p_mac The buffer where the resulting MAC will be placed
* upon success
* \param[in] mac_length The length in bytes of the `p_mac` buffer
*/
typedef psa_status_t (*psa_drv_mac_transparent_t)(const uint8_t *p_input,
size_t input_length,
const uint8_t *p_key,
size_t key_length,
psa_algorithm_t alg,
uint8_t *p_mac,
size_t mac_length);
/** \brief The function prototype for a one-shot operation of a transparent-key
* MAC Verify operation
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_mac_transparent_<ALGO>_<MAC_VARIANT>_verify
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is
* the specific variant of a MAC operation (such as HMAC or CMAC)
*
* \param[in] p_input A buffer containing the data to be MACed
* \param[in] input_length The length in bytes of the `p_input` data
* \param[in] p_key A buffer containing the key material to be used
* for the MAC operation
* \param[in] key_length The length in bytes of the `p_key` data
* \param[in] alg The algorithm to be performed
* \param[in] p_mac The MAC data to be compared
* \param[in] mac_length The length in bytes of the `p_mac` buffer
*
* \retval PSA_SUCCESS
* The operation completed successfully and the comparison matched
*/
typedef psa_status_t (*psa_drv_mac_transparent_verify_t)(const uint8_t *p_input,
size_t input_length,
const uint8_t *p_key,
size_t key_length,
psa_algorithm_t alg,
const uint8_t *p_mac,
size_t mac_length);
/**@}*/
/** \defgroup transparent_cipher Transparent Block Cipher
* Encryption and Decryption using transparent keys in block modes other than
* ECB must be done in multiple parts, using the following flow:
* - `psa_drv_cipher_transparent_setup_t`
* - `psa_drv_cipher_transparent_set_iv_t` (optional depending upon block mode)
* - `psa_drv_cipher_transparent_update_t`
* - ...
* - `psa_drv_cipher_transparent_finish_t`
* If a previously started Transparent Cipher operation needs to be terminated,
* it should be done so by the `psa_drv_cipher_transparent_abort_t`. Failure to do
* so may result in allocated resources not being freed or in other undefined
* behavior.
*/
/**@{*/
/** \brief The hardware-specific transparent-key Cipher context structure
*
* The contents of this structure are implementation dependent and are
* therefore not described here.
*/
typedef struct psa_drv_cipher_transparent_context_s psa_drv_cipher_transparent_context_t;
/** \brief The function prototype for the setup operation of transparent-key
* block cipher operations.
* Functions that implement the prototype should be named in the following
* conventions:
* ~~~~~~~~~~~~~{.c}
* psa_drv_cipher_transparent_setup_<CIPHER_NAME>_<MODE>
* ~~~~~~~~~~~~~
* Where
* - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES)
* - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR)
* or for stream ciphers:
* ~~~~~~~~~~~~~{.c}
* psa_drv_cipher_transparent_setup_<CIPHER_NAME>
* ~~~~~~~~~~~~~
* Where `CIPHER_NAME` is the name of a stream cipher (i.e. RC4)
*
* \param[in,out] p_context A structure that will contain the
* hardware-specific cipher context
* \param[in] direction Indicates if the operation is an encrypt or a
* decrypt
* \param[in] p_key_data A buffer containing the cleartext key material
* to be used in the operation
* \param[in] key_data_size The size in bytes of the key material
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_cipher_transparent_setup_t)(psa_drv_cipher_transparent_context_t *p_context,
psa_encrypt_or_decrypt_t direction,
const uint8_t *p_key_data,
size_t key_data_size);
/** \brief The function prototype for the set initialization vector operation
* of transparent-key block cipher operations
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_cipher_transparent_set_iv_<CIPHER_NAME>_<MODE>
* ~~~~~~~~~~~~~
* Where
* - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES)
* - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR)
*
* \param[in,out] p_context A structure that contains the previously setup
* hardware-specific cipher context
* \param[in] p_iv A buffer containing the initialization vecotr
* \param[in] iv_length The size in bytes of the contents of `p_iv`
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_cipher_transparent_set_iv_t)(psa_drv_cipher_transparent_context_t *p_context,
const uint8_t *p_iv,
size_t iv_length);
/** \brief The function prototype for the update operation of transparent-key
* block cipher operations.
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_cipher_transparent_update_<CIPHER_NAME>_<MODE>
* ~~~~~~~~~~~~~
* Where
* - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES)
* - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR)
*
* \param[in,out] p_context A hardware-specific structure for the
* previously started cipher operation
* \param[in] p_input A buffer containing the data to be
* encrypted or decrypted
* \param[in] input_size The size in bytes of the `p_input` buffer
* \param[out] p_output A caller-allocated buffer where the
* generated output will be placed
* \param[in] output_size The size in bytes of the `p_output` buffer
* \param[out] p_output_length After completion, will contain the number
* of bytes placed in the `p_output` buffer
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_cipher_transparent_update_t)(psa_drv_cipher_transparent_context_t *p_context,
const uint8_t *p_input,
size_t input_size,
uint8_t *p_output,
size_t output_size,
size_t *p_output_length);
/** \brief The function prototype for the finish operation of transparent-key
* block cipher operations.
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_cipher_transparent_finish_<CIPHER_NAME>_<MODE>
* ~~~~~~~~~~~~~
* Where
* - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES)
* - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR)
*
* \param[in,out] p_context A hardware-specific structure for the
* previously started cipher operation
* \param[out] p_output A caller-allocated buffer where the generated
* output will be placed
* \param[in] output_size The size in bytes of the `p_output` buffer
* \param[out] p_output_length After completion, will contain the number of
* bytes placed in the `p_output` buffer
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_cipher_transparent_finish_t)(psa_drv_cipher_transparent_context_t *p_context,
uint8_t *p_output,
size_t output_size,
size_t *p_output_length);
/** \brief The function prototype for the abort operation of transparent-key
* block cipher operations.
*
* Functions that implement the following prototype should be named in the
* following convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_cipher_transparent_abort_<CIPHER_NAME>_<MODE>
* ~~~~~~~~~~~~~
* Where
* - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES)
* - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR)
*
* \param[in,out] p_context A hardware-specific structure for the
* previously started cipher operation
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_cipher_transparent_abort_t)(psa_drv_cipher_transparent_context_t *p_context);
/**@}*/
/** \defgroup aead_transparent AEAD Transparent
*
* Authenticated Encryption with Additional Data (AEAD) operations with
* transparent keys must be done in one function call. While this creates a
* burden for implementers as there must be sufficient space in memory for the
* entire message, it prevents decrypted data from being made available before
* the authentication operation is complete and the data is known to be
* authentic.
*/
/**@{*/
/** Process an authenticated encryption operation using an opaque key.
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_aead_<ALGO>_encrypt
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the AEAD algorithm
*
* \param[in] p_key A pointer to the key material
* \param[in] key_length The size in bytes of the key material
* \param[in] alg The AEAD algorithm to compute
* (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_AEAD(`alg`) is true)
* \param[in] nonce Nonce or IV to use
* \param[in] nonce_length Size of the `nonce` buffer in bytes
* \param[in] additional_data Additional data that will be MACed
* but not encrypted.
* \param[in] additional_data_length Size of `additional_data` in bytes
* \param[in] plaintext Data that will be MACed and
* encrypted.
* \param[in] plaintext_length Size of `plaintext` in bytes
* \param[out] ciphertext Output buffer for the authenticated and
* encrypted data. The additional data is
* not part of this output. For algorithms
* where the encrypted data and the
* authentication tag are defined as
* separate outputs, the authentication
* tag is appended to the encrypted data.
* \param[in] ciphertext_size Size of the `ciphertext` buffer in
* bytes
* This must be at least
* #PSA_AEAD_ENCRYPT_OUTPUT_SIZE(`alg`,
* `plaintext_length`).
* \param[out] ciphertext_length On success, the size of the output in
* the `ciphertext` buffer
*
* \retval #PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_aead_transparent_encrypt_t)(const uint8_t *p_key,
size_t key_length,
psa_algorithm_t alg,
const uint8_t *nonce,
size_t nonce_length,
const uint8_t *additional_data,
size_t additional_data_length,
const uint8_t *plaintext,
size_t plaintext_length,
uint8_t *ciphertext,
size_t ciphertext_size,
size_t *ciphertext_length);
/** Process an authenticated decryption operation using an opaque key.
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_aead_<ALGO>_decrypt
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the AEAD algorithm
* \param[in] p_key A pointer to the key material
* \param[in] key_length The size in bytes of the key material
* \param[in] alg The AEAD algorithm to compute
* (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_AEAD(`alg`) is true)
* \param[in] nonce Nonce or IV to use
* \param[in] nonce_length Size of the `nonce` buffer in bytes
* \param[in] additional_data Additional data that has been MACed
* but not encrypted
* \param[in] additional_data_length Size of `additional_data` in bytes
* \param[in] ciphertext Data that has been MACed and
* encrypted
* For algorithms where the encrypted data
* and the authentication tag are defined
* as separate inputs, the buffer must
* contain the encrypted data followed by
* the authentication tag.
* \param[in] ciphertext_length Size of `ciphertext` in bytes
* \param[out] plaintext Output buffer for the decrypted data
* \param[in] plaintext_size Size of the `plaintext` buffer in
* bytes
* This must be at least
* #PSA_AEAD_DECRYPT_OUTPUT_SIZE(`alg`,
* `ciphertext_length`).
* \param[out] plaintext_length On success, the size of the output
* in the \b plaintext buffer
*
* \retval #PSA_SUCCESS
* Success.
*/
typedef psa_status_t (*psa_drv_aead_transparent_decrypt_t)(const uint8_t *p_key,
size_t key_length,
psa_algorithm_t alg,
const uint8_t *nonce,
size_t nonce_length,
const uint8_t *additional_data,
size_t additional_data_length,
const uint8_t *ciphertext,
size_t ciphertext_length,
uint8_t *plaintext,
size_t plaintext_size,
size_t *plaintext_length);
/**@}*/
/** \defgroup transparent_asymmetric Transparent Asymmetric Cryptography
*
* Since the amount of data that can (or should) be encrypted or signed using
* asymmetric keys is limited by the key size, asymmetric key operations using
* transparent keys must be done in single function calls.
*/
/**@{*/
/**
* \brief A function that signs a hash or short message with a transparent
* asymmetric private key
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_asymmetric_<ALGO>_sign
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the signing algorithm
*
* \param[in] p_key A buffer containing the private key
* material
* \param[in] key_size The size in bytes of the `p_key` data
* \param[in] alg A signature algorithm that is compatible
* with the type of `p_key`
* \param[in] p_hash The hash or message to sign
* \param[in] hash_length Size of the `p_hash` buffer in bytes
* \param[out] p_signature Buffer where the signature is to be written
* \param[in] signature_size Size of the `p_signature` buffer in bytes
* \param[out] p_signature_length On success, the number of bytes
* that make up the returned signature value
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_asymmetric_transparent_sign_t)(const uint8_t *p_key,
size_t key_size,
psa_algorithm_t alg,
const uint8_t *p_hash,
size_t hash_length,
uint8_t *p_signature,
size_t signature_size,
size_t *p_signature_length);
/**
* \brief A function that verifies the signature a hash or short message using
* a transparent asymmetric public key
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_asymmetric_<ALGO>_verify
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the signing algorithm
*
* \param[in] p_key A buffer containing the public key material
* \param[in] key_size The size in bytes of the `p_key` data
* \param[in] alg A signature algorithm that is compatible with
* the type of `key`
* \param[in] p_hash The hash or message whose signature is to be
* verified
* \param[in] hash_length Size of the `p_hash` buffer in bytes
* \param[in] p_signature Buffer containing the signature to verify
* \param[in] signature_length Size of the `p_signature` buffer in bytes
*
* \retval PSA_SUCCESS
* The signature is valid.
*/
typedef psa_status_t (*psa_drv_asymmetric_transparent_verify_t)(const uint8_t *p_key,
size_t key_size,
psa_algorithm_t alg,
const uint8_t *p_hash,
size_t hash_length,
const uint8_t *p_signature,
size_t signature_length);
/**
* \brief A function that encrypts a short message with a transparent
* asymmetric public key
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_asymmetric_<ALGO>_encrypt
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the encryption algorithm
*
* \param[in] p_key A buffer containing the public key material
* \param[in] key_size The size in bytes of the `p_key` data
* \param[in] alg An asymmetric encryption algorithm that is
* compatible with the type of `key`
* \param[in] p_input The message to encrypt
* \param[in] input_length Size of the `p_input` buffer in bytes
* \param[in] p_salt A salt or label, if supported by the
* encryption algorithm
* If the algorithm does not support a
* salt, pass `NULL`
* If the algorithm supports an optional
* salt and you do not want to pass a salt,
* pass `NULL`.
* For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is
* supported.
* \param[in] salt_length Size of the `p_salt` buffer in bytes
* If `p_salt` is `NULL`, pass 0.
* \param[out] p_output Buffer where the encrypted message is to
* be written
* \param[in] output_size Size of the `p_output` buffer in bytes
* \param[out] p_output_length On success, the number of bytes
* that make up the returned output
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_asymmetric_transparent_encrypt_t)(const uint8_t *p_key,
size_t key_size,
psa_algorithm_t alg,
const uint8_t *p_input,
size_t input_length,
const uint8_t *p_salt,
size_t salt_length,
uint8_t *p_output,
size_t output_size,
size_t *p_output_length);
/**
* \brief Decrypt a short message with a transparent asymmetric private key
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_asymmetric_<ALGO>_decrypt
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the encryption algorithm
*
* \param[in] p_key A buffer containing the private key material
* \param[in] key_size The size in bytes of the `p_key` data
* \param[in] alg An asymmetric encryption algorithm that is
* compatible with the type of `key`
* \param[in] p_input The message to decrypt
* \param[in] input_length Size of the `p_input` buffer in bytes
* \param[in] p_salt A salt or label, if supported by the
* encryption algorithm
* If the algorithm does not support a
* salt, pass `NULL`.
* If the algorithm supports an optional
* salt and you do not want to pass a salt,
* pass `NULL`.
* For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is
* supported
* \param[in] salt_length Size of the `p_salt` buffer in bytes
* If `p_salt` is `NULL`, pass 0
* \param[out] p_output Buffer where the decrypted message is to
* be written
* \param[in] output_size Size of the `p_output` buffer in bytes
* \param[out] p_output_length On success, the number of bytes
* that make up the returned output
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_asymmetric_transparent_decrypt_t)(const uint8_t *p_key,
size_t key_size,
psa_algorithm_t alg,
const uint8_t *p_input,
size_t input_length,
const uint8_t *p_salt,
size_t salt_length,
uint8_t *p_output,
size_t output_size,
size_t *p_output_length);
/**@}*/
#ifdef __cplusplus
}
#endif
#endif /* PSA_CRYPTO_ACCEL_DRIVER_H */

View File

@ -0,0 +1,54 @@
/**
* \file psa/crypto_driver_common.h
* \brief Definitions for all PSA crypto drivers
*
* This file contains common definitions shared by all PSA crypto drivers.
* Do not include it directly: instead, include the header file(s) for
* the type(s) of driver that you are implementing. For example, if
* you are writing a driver for a chip that provides both a hardware
* random generator and an accelerator for some cryptographic algorithms,
* include `psa/crypto_entropy_driver.h` and `psa/crypto_accel_driver.h`.
*
* This file is part of the PSA Crypto Driver Model, containing functions for
* driver developers to implement to enable hardware to be called in a
* standardized way by a PSA Cryptographic API implementation. The functions
* comprising the driver model, which driver authors implement, are not
* intended to be called by application developers.
*/
/*
* Copyright (C) 2018, 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.
*/
#ifndef PSA_CRYPTO_DRIVER_COMMON_H
#define PSA_CRYPTO_DRIVER_COMMON_H
#include <stddef.h>
#include <stdint.h>
/* Include type definitions (psa_status_t, psa_algorithm_t,
* psa_key_type_t, etc.) and macros to build and analyze values
* of these types. */
#include "crypto_types.h"
#include "crypto_values.h"
/** For encrypt-decrypt functions, whether the operation is an encryption
* or a decryption. */
typedef enum {
PSA_CRYPTO_DRIVER_DECRYPT,
PSA_CRYPTO_DRIVER_ENCRYPT
} psa_encrypt_or_decrypt_t;
#endif /* PSA_CRYPTO_DRIVER_COMMON_H */

View File

@ -0,0 +1,111 @@
/**
* \file psa/crypto_entropy_driver.h
* \brief PSA entropy source driver module
*
* This header declares types and function signatures for entropy sources.
*
* This file is part of the PSA Crypto Driver Model, containing functions for
* driver developers to implement to enable hardware to be called in a
* standardized way by a PSA Cryptographic API implementation. The functions
* comprising the driver model, which driver authors implement, are not
* intended to be called by application developers.
*/
/*
* Copyright (C) 2018, 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.
*/
#ifndef PSA_CRYPTO_ENTROPY_DRIVER_H
#define PSA_CRYPTO_ENTROPY_DRIVER_H
#include "crypto_driver_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup driver_rng Entropy Generation
*/
/**@{*/
/** \brief A hardware-specific structure for a entropy providing hardware
*/
typedef struct psa_drv_entropy_context_s psa_drv_entropy_context_t;
/** \brief Initialize an entropy driver
*
*
* \param[in,out] p_context A hardware-specific structure
* containing any context information for
* the implementation
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_entropy_init_t)(psa_drv_entropy_context_t *p_context);
/** \brief Get a specified number of bits from the entropy source
*
* It retrives `buffer_size` bytes of data from the entropy source. The entropy
* source will always fill the provided buffer to its full size, however, most
* entropy sources have biases, and the actual amount of entropy contained in
* the buffer will be less than the number of bytes.
* The driver will return the actual number of bytes of entropy placed in the
* buffer in `p_received_entropy_bytes`.
* A PSA Crypto API implementation will likely feed the output of this function
* into a Digital Random Bit Generator (DRBG), and typically has a minimum
* amount of entropy that it needs.
* To accomplish this, the PSA Crypto implementation should be designed to call
* this function multiple times until it has received the required amount of
* entropy from the entropy source.
*
* \param[in,out] p_context A hardware-specific structure
* containing any context information
* for the implementation
* \param[out] p_buffer A caller-allocated buffer for the
* retrieved entropy to be placed in
* \param[in] buffer_size The allocated size of `p_buffer`
* \param[out] p_received_entropy_bits The amount of entropy (in bits)
* actually provided in `p_buffer`
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_entropy_get_bits_t)(psa_drv_entropy_context_t *p_context,
uint8_t *p_buffer,
uint32_t buffer_size,
uint32_t *p_received_entropy_bits);
/**
* \brief A struct containing all of the function pointers needed to interface
* to an entropy source
*
* PSA Crypto API implementations should populate instances of the table as
* appropriate upon startup.
*
* If one of the functions is not implemented, it should be set to NULL.
*/
typedef struct {
/** Function that performs initialization for the entropy source */
psa_drv_entropy_init_t *p_init;
/** Function that performs the get_bits operation for the entropy source
*/
psa_drv_entropy_get_bits_t *p_get_bits;
} psa_drv_entropy_t;
/**@}*/
#ifdef __cplusplus
}
#endif
#endif /* PSA_CRYPTO_ENTROPY_DRIVER_H */

View File

@ -46,7 +46,7 @@
/* PSA requires several types which C99 provides in stdint.h. */
#include <stdint.h>
/* Integral type representing a key slot number. */
typedef uint16_t psa_key_slot_t;
/* Integral type representing a key handle. */
typedef uint16_t psa_key_handle_t;
#endif /* PSA_CRYPTO_PLATFORM_H */

View File

@ -1,8 +1,14 @@
/**
* \file psa/crypto_driver.h
* \brief Platform Security Architecture cryptographic driver module
* \file psa/crypto_se_driver.h
* \brief PSA external cryptoprocessor driver module
*
* This file describes the PSA Crypto Driver Model, containing functions for
* This header declares types and function signatures for cryptography
* drivers that access key material via opaque references. This is
* meant for cryptoprocessors that have a separate key storage from the
* space in which the PSA Crypto implementation runs, typically secure
* elements.
*
* This file is part of the PSA Crypto Driver Model, containing functions for
* driver developers to implement to enable hardware to be called in a
* standardized way by a PSA Cryptographic API implementation. The functions
* comprising the driver model, which driver authors implement, are not
@ -25,29 +31,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef PSA_CRYPTO_DRIVER_H
#define PSA_CRYPTO_DRIVER_H
#ifndef PSA_CRYPTO_SE_DRIVER_H
#define PSA_CRYPTO_SE_DRIVER_H
#include <stddef.h>
#include <stdint.h>
#include "crypto_driver_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/** The following types are redefinitions from the psa/crypto.h file.
* It is intended that these will be moved to a new common header file to
* avoid duplication. They are included here for expediency in publication.
*/
typedef uint32_t psa_status_t;
typedef uint32_t psa_algorithm_t;
typedef uint8_t psa_encrypt_or_decrypt_t;
/** An internal designation of a key slot between the core part of the
* PSA Crypto implementation and the driver. The meaning of this value
* is driver-dependent. */
typedef uint32_t psa_key_slot_t;
typedef uint32_t psa_key_type_t;
typedef uint32_t psa_key_usage_t;
#define PSA_CRYPTO_DRIVER_ENCRYPT 1
#define PSA_CRYPTO_DRIVER_DECRYPT 0
/** \defgroup opaque_mac Opaque Message Authentication Code
* Generation and authentication of Message Authentication Codes (MACs) using
@ -239,208 +235,6 @@ typedef struct {
} psa_drv_mac_opaque_t;
/**@}*/
/** \defgroup transparent_mac Transparent Message Authentication Code
* Generation and authentication of Message Authentication Codes (MACs) using
* transparent keys can be done either as a single function call (via the
* `psa_drv_mac_transparent_generate_t` or `psa_drv_mac_transparent_verify_t`
* functions), or in parts using the following sequence:
* - `psa_drv_mac_transparent_setup_t`
* - `psa_drv_mac_transparent_update_t`
* - `psa_drv_mac_transparent_update_t`
* - ...
* - `psa_drv_mac_transparent_finish_t` or `psa_drv_mac_transparent_finish_verify_t`
*
* If a previously started Transparent MAC operation needs to be terminated, it
* should be done so by the `psa_drv_mac_transparent_abort_t`. Failure to do so may
* result in allocated resources not being freed or in other undefined
* behavior.
*
*/
/**@{*/
/** \brief The hardware-specific transparent-key MAC context structure
*
* The contents of this structure are implementation dependent and are
* therefore not described here.
*/
typedef struct psa_drv_mac_transparent_context_s psa_drv_mac_transparent_context_t;
/** \brief The function prototype for the setup operation of a
* transparent-key MAC operation
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_mac_transparent_<ALGO>_<MAC_VARIANT>_setup
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the underlying primitive, and `MAC_VARIANT`
* is the specific variant of a MAC operation (such as HMAC or CMAC)
*
* \param[in,out] p_context A structure that will contain the
* hardware-specific MAC context
* \param[in] p_key A buffer containing the cleartext key material
* to be used in the operation
* \param[in] key_length The size in bytes of the key material
*
* \retval PSA_SUCCESS
* Success.
*/
typedef psa_status_t (*psa_drv_mac_transparent_setup_t)(psa_drv_mac_transparent_context_t *p_context,
const uint8_t *p_key,
size_t key_length);
/** \brief The function prototype for the update operation of a
* transparent-key MAC operation
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_mac_transparent_<ALGO>_<MAC_VARIANT>_update
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT`
* is the specific variant of a MAC operation (such as HMAC or CMAC)
*
* \param[in,out] p_context A hardware-specific structure for the
* previously-established MAC operation to be
* continued
* \param[in] p_input A buffer containing the message to be appended
* to the MAC operation
* \param[in] input_length The size in bytes of the input message buffer
*/
typedef psa_status_t (*psa_drv_mac_transparent_update_t)(psa_drv_mac_transparent_context_t *p_context,
const uint8_t *p_input,
size_t input_length);
/** \brief The function prototype for the finish operation of a
* transparent-key MAC operation
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_mac_transparent_<ALGO>_<MAC_VARIANT>_finish
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is
* the specific variant of a MAC operation (such as HMAC or CMAC)
*
* \param[in,out] p_context A hardware-specific structure for the
* previously started MAC operation to be
* finished
* \param[out] p_mac A buffer where the generated MAC will be placed
* \param[in] mac_length The size in bytes of the buffer that has been
* allocated for the `p_mac` buffer
*
* \retval PSA_SUCCESS
* Success.
*/
typedef psa_status_t (*psa_drv_mac_transparent_finish_t)(psa_drv_mac_transparent_context_t *p_context,
uint8_t *p_mac,
size_t mac_length);
/** \brief The function prototype for the finish and verify operation of a
* transparent-key MAC operation
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_mac_transparent_<ALGO>_<MAC_VARIANT>_finish_verify
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is
* the specific variant of a MAC operation (such as HMAC or CMAC)
*
* \param[in,out] p_context A hardware-specific structure for the
* previously started MAC operation to be
* verified and finished
* \param[in] p_mac A buffer containing the MAC that will be used
* for verification
* \param[in] mac_length The size in bytes of the data in the `p_mac`
* buffer
*
* \retval PSA_SUCCESS
* The operation completed successfully and the comparison matched
*/
typedef psa_status_t (*psa_drv_mac_transparent_finish_verify_t)(psa_drv_mac_transparent_context_t *p_context,
const uint8_t *p_mac,
size_t mac_length);
/** \brief The function prototype for the abort operation for a previously
* started transparent-key MAC operation
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_mac_transparent_<ALGO>_<MAC_VARIANT>_abort
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is
* the specific variant of a MAC operation (such as HMAC or CMAC)
*
* \param[in,out] p_context A hardware-specific structure for the
* previously started MAC operation to be
* aborted
*
*/
typedef psa_status_t (*psa_drv_mac_transparent_abort_t)(psa_drv_mac_transparent_context_t *p_context);
/** \brief The function prototype for a one-shot operation of a transparent-key
* MAC operation
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_mac_transparent_<ALGO>_<MAC_VARIANT>
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is
* the specific variant of a MAC operation (such as HMAC or CMAC)
*
* \param[in] p_input A buffer containing the data to be MACed
* \param[in] input_length The length in bytes of the `p_input` data
* \param[in] p_key A buffer containing the key material to be used
* for the MAC operation
* \param[in] key_length The length in bytes of the `p_key` data
* \param[in] alg The algorithm to be performed
* \param[out] p_mac The buffer where the resulting MAC will be placed
* upon success
* \param[in] mac_length The length in bytes of the `p_mac` buffer
*/
typedef psa_status_t (*psa_drv_mac_transparent_t)(const uint8_t *p_input,
size_t input_length,
const uint8_t *p_key,
size_t key_length,
psa_algorithm_t alg,
uint8_t *p_mac,
size_t mac_length);
/** \brief The function prototype for a one-shot operation of a transparent-key
* MAC Verify operation
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_mac_transparent_<ALGO>_<MAC_VARIANT>_verify
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is
* the specific variant of a MAC operation (such as HMAC or CMAC)
*
* \param[in] p_input A buffer containing the data to be MACed
* \param[in] input_length The length in bytes of the `p_input` data
* \param[in] p_key A buffer containing the key material to be used
* for the MAC operation
* \param[in] key_length The length in bytes of the `p_key` data
* \param[in] alg The algorithm to be performed
* \param[in] p_mac The MAC data to be compared
* \param[in] mac_length The length in bytes of the `p_mac` buffer
*
* \retval PSA_SUCCESS
* The operation completed successfully and the comparison matched
*/
typedef psa_status_t (*psa_drv_mac_transparent_verify_t)(const uint8_t *p_input,
size_t input_length,
const uint8_t *p_key,
size_t key_length,
psa_algorithm_t alg,
const uint8_t *p_mac,
size_t mac_length);
/**@}*/
/** \defgroup opaque_cipher Opaque Symmetric Ciphers
*
* Encryption and Decryption using opaque keys in block modes other than ECB
@ -618,269 +412,6 @@ typedef struct {
/**@}*/
/** \defgroup transparent_cipher Transparent Block Cipher
* Encryption and Decryption using transparent keys in block modes other than
* ECB must be done in multiple parts, using the following flow:
* - `psa_drv_cipher_transparent_setup_t`
* - `psa_drv_cipher_transparent_set_iv_t` (optional depending upon block mode)
* - `psa_drv_cipher_transparent_update_t`
* - ...
* - `psa_drv_cipher_transparent_finish_t`
* If a previously started Transparent Cipher operation needs to be terminated,
* it should be done so by the `psa_drv_cipher_transparent_abort_t`. Failure to do
* so may result in allocated resources not being freed or in other undefined
* behavior.
*/
/**@{*/
/** \brief The hardware-specific transparent-key Cipher context structure
*
* The contents of this structure are implementation dependent and are
* therefore not described here.
*/
typedef struct psa_drv_cipher_transparent_context_s psa_drv_cipher_transparent_context_t;
/** \brief The function prototype for the setup operation of transparent-key
* block cipher operations.
* Functions that implement the prototype should be named in the following
* conventions:
* ~~~~~~~~~~~~~{.c}
* psa_drv_cipher_transparent_setup_<CIPHER_NAME>_<MODE>
* ~~~~~~~~~~~~~
* Where
* - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES)
* - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR)
* or for stream ciphers:
* ~~~~~~~~~~~~~{.c}
* psa_drv_cipher_transparent_setup_<CIPHER_NAME>
* ~~~~~~~~~~~~~
* Where `CIPHER_NAME` is the name of a stream cipher (i.e. RC4)
*
* \param[in,out] p_context A structure that will contain the
* hardware-specific cipher context
* \param[in] direction Indicates if the operation is an encrypt or a
* decrypt
* \param[in] p_key_data A buffer containing the cleartext key material
* to be used in the operation
* \param[in] key_data_size The size in bytes of the key material
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_cipher_transparent_setup_t)(psa_drv_cipher_transparent_context_t *p_context,
psa_encrypt_or_decrypt_t direction,
const uint8_t *p_key_data,
size_t key_data_size);
/** \brief The function prototype for the set initialization vector operation
* of transparent-key block cipher operations
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_cipher_transparent_set_iv_<CIPHER_NAME>_<MODE>
* ~~~~~~~~~~~~~
* Where
* - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES)
* - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR)
*
* \param[in,out] p_context A structure that contains the previously setup
* hardware-specific cipher context
* \param[in] p_iv A buffer containing the initialization vecotr
* \param[in] iv_length The size in bytes of the contents of `p_iv`
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_cipher_transparent_set_iv_t)(psa_drv_cipher_transparent_context_t *p_context,
const uint8_t *p_iv,
size_t iv_length);
/** \brief The function prototype for the update operation of transparent-key
* block cipher operations.
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_cipher_transparent_update_<CIPHER_NAME>_<MODE>
* ~~~~~~~~~~~~~
* Where
* - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES)
* - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR)
*
* \param[in,out] p_context A hardware-specific structure for the
* previously started cipher operation
* \param[in] p_input A buffer containing the data to be
* encrypted or decrypted
* \param[in] input_size The size in bytes of the `p_input` buffer
* \param[out] p_output A caller-allocated buffer where the
* generated output will be placed
* \param[in] output_size The size in bytes of the `p_output` buffer
* \param[out] p_output_length After completion, will contain the number
* of bytes placed in the `p_output` buffer
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_cipher_transparent_update_t)(psa_drv_cipher_transparent_context_t *p_context,
const uint8_t *p_input,
size_t input_size,
uint8_t *p_output,
size_t output_size,
size_t *p_output_length);
/** \brief The function prototype for the finish operation of transparent-key
* block cipher operations.
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_cipher_transparent_finish_<CIPHER_NAME>_<MODE>
* ~~~~~~~~~~~~~
* Where
* - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES)
* - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR)
*
* \param[in,out] p_context A hardware-specific structure for the
* previously started cipher operation
* \param[out] p_output A caller-allocated buffer where the generated
* output will be placed
* \param[in] output_size The size in bytes of the `p_output` buffer
* \param[out] p_output_length After completion, will contain the number of
* bytes placed in the `p_output` buffer
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_cipher_transparent_finish_t)(psa_drv_cipher_transparent_context_t *p_context,
uint8_t *p_output,
size_t output_size,
size_t *p_output_length);
/** \brief The function prototype for the abort operation of transparent-key
* block cipher operations.
*
* Functions that implement the following prototype should be named in the
* following convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_cipher_transparent_abort_<CIPHER_NAME>_<MODE>
* ~~~~~~~~~~~~~
* Where
* - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES)
* - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR)
*
* \param[in,out] p_context A hardware-specific structure for the
* previously started cipher operation
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_cipher_transparent_abort_t)(psa_drv_cipher_transparent_context_t *p_context);
/**@}*/
/** \defgroup driver_digest Message Digests
*
* Generation and authentication of Message Digests (aka hashes) must be done
* in parts using the following sequence:
* - `psa_drv_hash_setup_t`
* - `psa_drv_hash_update_t`
* - ...
* - `psa_drv_hash_finish_t`
*
* If a previously started Message Digest operation needs to be terminated
* before the `psa_drv_hash_finish_t` operation is complete, it should be aborted
* by the `psa_drv_hash_abort_t`. Failure to do so may result in allocated
* resources not being freed or in other undefined behavior.
*/
/**@{*/
/** \brief The hardware-specific hash context structure
*
* The contents of this structure are implementation dependent and are
* therefore not described here
*/
typedef struct psa_drv_hash_context_s psa_drv_hash_context_t;
/** \brief The function prototype for the start operation of a hash (message
* digest) operation
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_hash_<ALGO>_setup
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the underlying hash function
*
* \param[in,out] p_context A structure that will contain the
* hardware-specific hash context
*
* \retval PSA_SUCCESS Success.
*/
typedef psa_status_t (*psa_drv_hash_setup_t)(psa_drv_hash_context_t *p_context);
/** \brief The function prototype for the update operation of a hash (message
* digest) operation
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_hash_<ALGO>_update
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the underlying algorithm
*
* \param[in,out] p_context A hardware-specific structure for the
* previously-established hash operation to be
* continued
* \param[in] p_input A buffer containing the message to be appended
* to the hash operation
* \param[in] input_length The size in bytes of the input message buffer
*/
typedef psa_status_t (*psa_drv_hash_update_t)(psa_drv_hash_context_t *p_context,
const uint8_t *p_input,
size_t input_length);
/** \brief The prototype for the finish operation of a hash (message digest)
* operation
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_hash_<ALGO>_finish
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the underlying algorithm
*
* \param[in,out] p_context A hardware-specific structure for the
* previously started hash operation to be
* fiinished
* \param[out] p_output A buffer where the generated digest will be
* placed
* \param[in] output_size The size in bytes of the buffer that has been
* allocated for the `p_output` buffer
* \param[out] p_output_length The number of bytes placed in `p_output` after
* success
*
* \retval PSA_SUCCESS
* Success.
*/
typedef psa_status_t (*psa_drv_hash_finish_t)(psa_drv_hash_context_t *p_context,
uint8_t *p_output,
size_t output_size,
size_t *p_output_length);
/** \brief The function prototype for the abort operation of a hash (message
* digest) operation
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_hash_<ALGO>_abort
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the underlying algorithm
*
* \param[in,out] p_context A hardware-specific structure for the previously
* started hash operation to be aborted
*/
typedef void (*psa_drv_hash_abort_t)(psa_drv_hash_context_t *p_context);
/**@}*/
/** \defgroup opaque_asymmetric Opaque Asymmetric Cryptography
*
* Since the amount of data that can (or should) be encrypted or signed using
@ -1033,176 +564,6 @@ typedef struct {
/**@}*/
/** \defgroup transparent_asymmetric Transparent Asymmetric Cryptography
*
* Since the amount of data that can (or should) be encrypted or signed using
* asymmetric keys is limited by the key size, asymmetric key operations using
* transparent keys must be done in single function calls.
*/
/**@{*/
/**
* \brief A function that signs a hash or short message with a transparent
* asymmetric private key
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_asymmetric_<ALGO>_sign
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the signing algorithm
*
* \param[in] p_key A buffer containing the private key
* material
* \param[in] key_size The size in bytes of the `p_key` data
* \param[in] alg A signature algorithm that is compatible
* with the type of `p_key`
* \param[in] p_hash The hash or message to sign
* \param[in] hash_length Size of the `p_hash` buffer in bytes
* \param[out] p_signature Buffer where the signature is to be written
* \param[in] signature_size Size of the `p_signature` buffer in bytes
* \param[out] p_signature_length On success, the number of bytes
* that make up the returned signature value
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_asymmetric_transparent_sign_t)(const uint8_t *p_key,
size_t key_size,
psa_algorithm_t alg,
const uint8_t *p_hash,
size_t hash_length,
uint8_t *p_signature,
size_t signature_size,
size_t *p_signature_length);
/**
* \brief A function that verifies the signature a hash or short message using
* a transparent asymmetric public key
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_asymmetric_<ALGO>_verify
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the signing algorithm
*
* \param[in] p_key A buffer containing the public key material
* \param[in] key_size The size in bytes of the `p_key` data
* \param[in] alg A signature algorithm that is compatible with
* the type of `key`
* \param[in] p_hash The hash or message whose signature is to be
* verified
* \param[in] hash_length Size of the `p_hash` buffer in bytes
* \param[in] p_signature Buffer containing the signature to verify
* \param[in] signature_length Size of the `p_signature` buffer in bytes
*
* \retval PSA_SUCCESS
* The signature is valid.
*/
typedef psa_status_t (*psa_drv_asymmetric_transparent_verify_t)(const uint8_t *p_key,
size_t key_size,
psa_algorithm_t alg,
const uint8_t *p_hash,
size_t hash_length,
const uint8_t *p_signature,
size_t signature_length);
/**
* \brief A function that encrypts a short message with a transparent
* asymmetric public key
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_asymmetric_<ALGO>_encrypt
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the encryption algorithm
*
* \param[in] p_key A buffer containing the public key material
* \param[in] key_size The size in bytes of the `p_key` data
* \param[in] alg An asymmetric encryption algorithm that is
* compatible with the type of `key`
* \param[in] p_input The message to encrypt
* \param[in] input_length Size of the `p_input` buffer in bytes
* \param[in] p_salt A salt or label, if supported by the
* encryption algorithm
* If the algorithm does not support a
* salt, pass `NULL`
* If the algorithm supports an optional
* salt and you do not want to pass a salt,
* pass `NULL`.
* For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is
* supported.
* \param[in] salt_length Size of the `p_salt` buffer in bytes
* If `p_salt` is `NULL`, pass 0.
* \param[out] p_output Buffer where the encrypted message is to
* be written
* \param[in] output_size Size of the `p_output` buffer in bytes
* \param[out] p_output_length On success, the number of bytes
* that make up the returned output
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_asymmetric_transparent_encrypt_t)(const uint8_t *p_key,
size_t key_size,
psa_algorithm_t alg,
const uint8_t *p_input,
size_t input_length,
const uint8_t *p_salt,
size_t salt_length,
uint8_t *p_output,
size_t output_size,
size_t *p_output_length);
/**
* \brief Decrypt a short message with a transparent asymmetric private key
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_asymmetric_<ALGO>_decrypt
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the encryption algorithm
*
* \param[in] p_key A buffer containing the private key material
* \param[in] key_size The size in bytes of the `p_key` data
* \param[in] alg An asymmetric encryption algorithm that is
* compatible with the type of `key`
* \param[in] p_input The message to decrypt
* \param[in] input_length Size of the `p_input` buffer in bytes
* \param[in] p_salt A salt or label, if supported by the
* encryption algorithm
* If the algorithm does not support a
* salt, pass `NULL`.
* If the algorithm supports an optional
* salt and you do not want to pass a salt,
* pass `NULL`.
* For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is
* supported
* \param[in] salt_length Size of the `p_salt` buffer in bytes
* If `p_salt` is `NULL`, pass 0
* \param[out] p_output Buffer where the decrypted message is to
* be written
* \param[in] output_size Size of the `p_output` buffer in bytes
* \param[out] p_output_length On success, the number of bytes
* that make up the returned output
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_asymmetric_transparent_decrypt_t)(const uint8_t *p_key,
size_t key_size,
psa_algorithm_t alg,
const uint8_t *p_input,
size_t input_length,
const uint8_t *p_salt,
size_t salt_length,
uint8_t *p_output,
size_t output_size,
size_t *p_output_length);
/**@}*/
/** \defgroup aead_opaque AEAD Opaque
* Authenticated Encryption with Additional Data (AEAD) operations with opaque
* keys must be done in one function call. While this creates a burden for
@ -1310,192 +671,6 @@ typedef struct {
} psa_drv_aead_opaque_t;
/**@}*/
/** \defgroup aead_transparent AEAD Transparent
*
* Authenticated Encryption with Additional Data (AEAD) operations with
* transparent keys must be done in one function call. While this creates a
* burden for implementers as there must be sufficient space in memory for the
* entire message, it prevents decrypted data from being made available before
* the authentication operation is complete and the data is known to be
* authentic.
*/
/**@{*/
/** Process an authenticated encryption operation using an opaque key.
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_aead_<ALGO>_encrypt
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the AEAD algorithm
*
* \param[in] p_key A pointer to the key material
* \param[in] key_length The size in bytes of the key material
* \param[in] alg The AEAD algorithm to compute
* (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_AEAD(`alg`) is true)
* \param[in] nonce Nonce or IV to use
* \param[in] nonce_length Size of the `nonce` buffer in bytes
* \param[in] additional_data Additional data that will be MACed
* but not encrypted.
* \param[in] additional_data_length Size of `additional_data` in bytes
* \param[in] plaintext Data that will be MACed and
* encrypted.
* \param[in] plaintext_length Size of `plaintext` in bytes
* \param[out] ciphertext Output buffer for the authenticated and
* encrypted data. The additional data is
* not part of this output. For algorithms
* where the encrypted data and the
* authentication tag are defined as
* separate outputs, the authentication
* tag is appended to the encrypted data.
* \param[in] ciphertext_size Size of the `ciphertext` buffer in
* bytes
* This must be at least
* #PSA_AEAD_ENCRYPT_OUTPUT_SIZE(`alg`,
* `plaintext_length`).
* \param[out] ciphertext_length On success, the size of the output in
* the `ciphertext` buffer
*
* \retval #PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_aead_transparent_encrypt_t)(const uint8_t *p_key,
size_t key_length,
psa_algorithm_t alg,
const uint8_t *nonce,
size_t nonce_length,
const uint8_t *additional_data,
size_t additional_data_length,
const uint8_t *plaintext,
size_t plaintext_length,
uint8_t *ciphertext,
size_t ciphertext_size,
size_t *ciphertext_length);
/** Process an authenticated decryption operation using an opaque key.
*
* Functions that implement the prototype should be named in the following
* convention:
* ~~~~~~~~~~~~~{.c}
* psa_drv_aead_<ALGO>_decrypt
* ~~~~~~~~~~~~~
* Where `ALGO` is the name of the AEAD algorithm
* \param[in] p_key A pointer to the key material
* \param[in] key_length The size in bytes of the key material
* \param[in] alg The AEAD algorithm to compute
* (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_AEAD(`alg`) is true)
* \param[in] nonce Nonce or IV to use
* \param[in] nonce_length Size of the `nonce` buffer in bytes
* \param[in] additional_data Additional data that has been MACed
* but not encrypted
* \param[in] additional_data_length Size of `additional_data` in bytes
* \param[in] ciphertext Data that has been MACed and
* encrypted
* For algorithms where the encrypted data
* and the authentication tag are defined
* as separate inputs, the buffer must
* contain the encrypted data followed by
* the authentication tag.
* \param[in] ciphertext_length Size of `ciphertext` in bytes
* \param[out] plaintext Output buffer for the decrypted data
* \param[in] plaintext_size Size of the `plaintext` buffer in
* bytes
* This must be at least
* #PSA_AEAD_DECRYPT_OUTPUT_SIZE(`alg`,
* `ciphertext_length`).
* \param[out] plaintext_length On success, the size of the output
* in the \b plaintext buffer
*
* \retval #PSA_SUCCESS
* Success.
*/
typedef psa_status_t (*psa_drv_aead_transparent_decrypt_t)(const uint8_t *p_key,
size_t key_length,
psa_algorithm_t alg,
const uint8_t *nonce,
size_t nonce_length,
const uint8_t *additional_data,
size_t additional_data_length,
const uint8_t *ciphertext,
size_t ciphertext_length,
uint8_t *plaintext,
size_t plaintext_size,
size_t *plaintext_length);
/**@}*/
/** \defgroup driver_rng Entropy Generation
*/
/**@{*/
/** \brief A hardware-specific structure for a entropy providing hardware
*/
typedef struct psa_drv_entropy_context_s psa_drv_entropy_context_t;
/** \brief Initialize an entropy driver
*
*
* \param[in,out] p_context A hardware-specific structure
* containing any context information for
* the implementation
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_entropy_init_t)(psa_drv_entropy_context_t *p_context);
/** \brief Get a specified number of bits from the entropy source
*
* It retrives `buffer_size` bytes of data from the entropy source. The entropy
* source will always fill the provided buffer to its full size, however, most
* entropy sources have biases, and the actual amount of entropy contained in
* the buffer will be less than the number of bytes.
* The driver will return the actual number of bytes of entropy placed in the
* buffer in `p_received_entropy_bytes`.
* A PSA Crypto API implementation will likely feed the output of this function
* into a Digital Random Bit Generator (DRBG), and typically has a minimum
* amount of entropy that it needs.
* To accomplish this, the PSA Crypto implementation should be designed to call
* this function multiple times until it has received the required amount of
* entropy from the entropy source.
*
* \param[in,out] p_context A hardware-specific structure
* containing any context information
* for the implementation
* \param[out] p_buffer A caller-allocated buffer for the
* retrieved entropy to be placed in
* \param[in] buffer_size The allocated size of `p_buffer`
* \param[out] p_received_entropy_bits The amount of entropy (in bits)
* actually provided in `p_buffer`
*
* \retval PSA_SUCCESS
*/
typedef psa_status_t (*psa_drv_entropy_get_bits_t)(psa_drv_entropy_context_t *p_context,
uint8_t *p_buffer,
uint32_t buffer_size,
uint32_t *p_received_entropy_bits);
/**
* \brief A struct containing all of the function pointers needed to interface
* to an entropy source
*
* PSA Crypto API implementations should populate instances of the table as
* appropriate upon startup.
*
* If one of the functions is not implemented, it should be set to NULL.
*/
typedef struct {
/** Function that performs initialization for the entropy source */
psa_drv_entropy_init_t *p_init;
/** Function that performs the get_bits operation for the entropy source
*/
psa_drv_entropy_get_bits_t *p_get_bits;
} psa_drv_entropy_t;
/**@}*/
/** \defgroup driver_key_management Key Management
* Currently, key management is limited to importing keys in the clear,
* destroying keys, and exporting keys in the clear.
@ -1784,4 +959,4 @@ typedef struct {
}
#endif
#endif /* PSA_CRYPTO_DRIVER_H */
#endif /* PSA_CRYPTO_SE_DRIVER_H */

View File

@ -50,6 +50,42 @@
#include MBEDTLS_CONFIG_FILE
#endif
#define PSA_BITS_TO_BYTES(bits) (((bits) + 7) / 8)
#define PSA_BYTES_TO_BITS(bytes) ((bytes) * 8)
/** The size of the output of psa_hash_finish(), in bytes.
*
* This is also the hash size that psa_hash_verify() expects.
*
* \param alg A hash algorithm (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_HASH(\p alg) is true), or an HMAC algorithm
* (#PSA_ALG_HMAC(\c hash_alg) where \c hash_alg is a
* hash algorithm).
*
* \return The hash size for the specified hash algorithm.
* If the hash algorithm is not recognized, return 0.
* An implementation may return either 0 or the correct size
* for a hash algorithm that it recognizes, but does not support.
*/
#define PSA_HASH_SIZE(alg) \
( \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD2 ? 16 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD4 ? 16 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD5 ? 16 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_RIPEMD160 ? 20 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_1 ? 20 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_224 ? 28 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_256 ? 32 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_384 ? 48 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512 ? 64 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_224 ? 28 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_256 ? 32 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_224 ? 28 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_256 ? 32 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_384 ? 48 : \
PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_512 ? 64 : \
0)
/** \def PSA_HASH_MAX_SIZE
*
* Maximum size of a hash.
@ -84,6 +120,26 @@
*/
#define PSA_MAC_MAX_SIZE PSA_HASH_MAX_SIZE
/** The tag size for an AEAD algorithm, in bytes.
*
* \param alg An AEAD algorithm
* (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_AEAD(\p alg) is true).
*
* \return The tag size for the specified algorithm.
* If the AEAD algorithm does not have an identified
* tag that can be distinguished from the rest of
* the ciphertext, return 0.
* If the AEAD algorithm is not recognized, return 0.
* An implementation may return either 0 or a
* correct size for an AEAD algorithm that it
* recognizes, but does not support.
*/
#define PSA_AEAD_TAG_LENGTH(alg) \
(PSA_ALG_IS_AEAD(alg) ? \
(((alg) & PSA_ALG_AEAD_TAG_LENGTH_MASK) >> PSA_AEAD_TAG_LENGTH_OFFSET) : \
0)
/* The maximum size of an RSA key on this implementation, in bits.
* This is a vendor-specific macro.
*
@ -236,6 +292,22 @@
(plaintext_length) - PSA_AEAD_TAG_LENGTH(alg) : \
0)
#define PSA_RSA_MINIMUM_PADDING_SIZE(alg) \
(PSA_ALG_IS_RSA_OAEP(alg) ? \
2 * PSA_HASH_FINAL_SIZE(PSA_ALG_RSA_OAEP_GET_HASH(alg)) + 1 : \
11 /*PKCS#1v1.5*/)
/**
* \brief ECDSA signature size for a given curve bit size
*
* \param curve_bits Curve size in bits.
* \return Signature size in bytes.
*
* \note This macro returns a compile-time constant if its argument is one.
*/
#define PSA_ECDSA_SIGNATURE_SIZE(curve_bits) \
(PSA_BITS_TO_BYTES(curve_bits) * 2)
/** Safe signature buffer size for psa_asymmetric_sign().
*
* This macro returns a safe buffer size for a signature using a key
@ -345,25 +417,16 @@
/* Maximum size of the export encoding of an RSA public key.
* Assumes that the public exponent is less than 2^32.
*
* SubjectPublicKeyInfo ::= SEQUENCE {
* algorithm AlgorithmIdentifier,
* subjectPublicKey BIT STRING } -- contains RSAPublicKey
* AlgorithmIdentifier ::= SEQUENCE {
* algorithm OBJECT IDENTIFIER,
* parameters NULL }
* RSAPublicKey ::= SEQUENCE {
* modulus INTEGER, -- n
* publicExponent INTEGER } -- e
*
* - 3 * 4 bytes of SEQUENCE overhead;
* - 1 + 1 + 9 bytes of algorithm (RSA OID);
* - 2 bytes of NULL;
* - 4 bytes of BIT STRING overhead;
* - 4 bytes of SEQUENCE overhead;
* - n : INTEGER;
* - 7 bytes for the public exponent.
*/
#define PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) \
(PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE(key_bits) + 36)
(PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE(key_bits) + 11)
/* Maximum size of the export encoding of an RSA key pair.
* Assumes thatthe public exponent is less than 2^32 and that the size
@ -430,26 +493,16 @@
/* Maximum size of the export encoding of an ECC public key.
*
* SubjectPublicKeyInfo ::= SEQUENCE {
* algorithm AlgorithmIdentifier,
* subjectPublicKey BIT STRING } -- contains ECPoint
* AlgorithmIdentifier ::= SEQUENCE {
* algorithm OBJECT IDENTIFIER,
* parameters OBJECT IDENTIFIER } -- namedCurve
* ECPoint ::= ...
* -- first 8 bits: 0x04;
* -- then x_P as a `ceiling(m/8)`-byte string, big endian;
* -- then y_P as a `ceiling(m/8)`-byte string, big endian;
* -- where `m` is the bit size associated with the curve.
* The representation of an ECC public key is:
* - The byte 0x04;
* - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
* - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
* - where m is the bit size associated with the curve.
*
* - 2 * 4 bytes of SEQUENCE overhead;
* - 1 + 1 + 7 bytes of algorithm (id-ecPublicKey OID);
* - 1 + 1 + 12 bytes of namedCurve OID;
* - 4 bytes of BIT STRING overhead;
* - 1 byte + 2 * point size in ECPoint.
* - 1 byte + 2 * point size.
*/
#define PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) \
(2 * PSA_BITS_TO_BYTES(key_bits) + 36)
(2 * PSA_BITS_TO_BYTES(key_bits) + 1)
/* Maximum size of the export encoding of an ECC key pair.
*

View File

@ -0,0 +1,101 @@
/**
* \file psa/crypto_types.h
*
* \brief PSA cryptography module: type aliases.
*
* \note This file may not be included directly. Applications must
* include psa/crypto.h. Drivers must include the appropriate driver
* header file.
*
* This file contains portable definitions of integral types for properties
* of cryptographic keys, designations of cryptographic algorithms, and
* error codes returned by the library.
*
* This header file does not declare any function.
*/
/*
* Copyright (C) 2018, 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)
*/
#ifndef PSA_CRYPTO_TYPES_H
#define PSA_CRYPTO_TYPES_H
#include <stdint.h>
/** \defgroup error Error codes
* @{
*/
/**
* \brief Function return status.
*
* This is either #PSA_SUCCESS (which is zero), indicating success,
* or a nonzero value indicating that an error occurred. Errors are
* encoded as one of the \c PSA_ERROR_xxx values defined here.
*/
typedef int32_t psa_status_t;
/**@}*/
/** \defgroup crypto_types Key and algorithm types
* @{
*/
/** \brief Encoding of a key type.
*/
typedef uint32_t psa_key_type_t;
/** The type of PSA elliptic curve identifiers. */
typedef uint16_t psa_ecc_curve_t;
/** \brief Encoding of a cryptographic algorithm.
*
* For algorithms that can be applied to multiple key types, this type
* does not encode the key type. For example, for symmetric ciphers
* based on a block cipher, #psa_algorithm_t encodes the block cipher
* mode and the padding mode while the block cipher itself is encoded
* via #psa_key_type_t.
*/
typedef uint32_t psa_algorithm_t;
/**@}*/
/** \defgroup key_lifetimes Key lifetimes
* @{
*/
/** Encoding of key lifetimes.
*/
typedef uint32_t psa_key_lifetime_t;
/** Encoding of identifiers of persistent keys.
*/
typedef uint32_t psa_key_id_t;
/**@}*/
/** \defgroup policy Key policies
* @{
*/
/** \brief Encoding of permitted usage on a key. */
typedef uint32_t psa_key_usage_t;
/**@}*/
#endif /* PSA_CRYPTO_TYPES_H */

File diff suppressed because it is too large Load Diff

View File

@ -85,6 +85,13 @@ struct psa_hash_operation_s
} ctx;
};
#define PSA_HASH_OPERATION_INIT {0, {0}}
static inline struct psa_hash_operation_s psa_hash_operation_init( void )
{
const struct psa_hash_operation_s v = PSA_HASH_OPERATION_INIT;
return( v );
}
#if defined(MBEDTLS_MD_C)
typedef struct
{
@ -116,6 +123,13 @@ struct psa_mac_operation_s
} ctx;
};
#define PSA_MAC_OPERATION_INIT {0, 0, 0, 0, 0, 0, 0, {0}}
static inline struct psa_mac_operation_s psa_mac_operation_init( void )
{
const struct psa_mac_operation_s v = PSA_MAC_OPERATION_INIT;
return( v );
}
struct psa_cipher_operation_s
{
psa_algorithm_t alg;
@ -126,10 +140,18 @@ struct psa_cipher_operation_s
uint8_t block_size;
union
{
unsigned dummy; /* Enable easier initializing of the union. */
mbedtls_cipher_context_t cipher;
} ctx;
};
#define PSA_CIPHER_OPERATION_INIT {0, 0, 0, 0, 0, 0, {0}}
static inline struct psa_cipher_operation_s psa_cipher_operation_init( void )
{
const struct psa_cipher_operation_s v = PSA_CIPHER_OPERATION_INIT;
return( v );
}
#if defined(MBEDTLS_MD_C)
typedef struct
{
@ -208,4 +230,11 @@ struct psa_key_policy_s
psa_algorithm_t alg;
};
#define PSA_KEY_POLICY_INIT {0, 0}
static inline struct psa_key_policy_s psa_key_policy_init( void )
{
const struct psa_key_policy_s v = PSA_KEY_POLICY_INIT;
return( v );
}
#endif /* PSA_CRYPTO_STRUCT_H */

View File

@ -0,0 +1,99 @@
/*
* PSA crypto core internal interfaces
*/
/* Copyright (C) 2018, 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)
*/
#ifndef PSA_CRYPTO_CORE_H
#define PSA_CRYPTO_CORE_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "psa/crypto.h"
#include "mbedtls/ecp.h"
#include "mbedtls/rsa.h"
/** The data structure representing a key slot, containing key material
* and metadata for one key.
*/
typedef struct
{
psa_key_type_t type;
psa_key_policy_t policy;
psa_key_lifetime_t lifetime;
psa_key_id_t persistent_storage_id;
unsigned allocated : 1;
union
{
struct raw_data
{
uint8_t *data;
size_t bytes;
} raw;
#if defined(MBEDTLS_RSA_C)
mbedtls_rsa_context *rsa;
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_ECP_C)
mbedtls_ecp_keypair *ecp;
#endif /* MBEDTLS_ECP_C */
} data;
} psa_key_slot_t;
/** Completely wipe a slot in memory, including its policy.
*
* Persistent storage is not affected.
*
* \param[in,out] slot The key slot to wipe.
*
* \retval PSA_SUCCESS
* Success. This includes the case of a key slot that was
* already fully wiped.
* \retval PSA_ERROR_TAMPERING_DETECTED
*/
psa_status_t psa_wipe_key_slot( psa_key_slot_t *slot );
/** Import key data into a slot.
*
* `slot->type` must have been set previously.
* This function assumes that the slot does not contain any key material yet.
* On failure, the slot content is unchanged.
*
* Persistent storage is not affected.
*
* \param[in,out] slot The key slot to import data into.
* Its `type` field must have previously been set to
* the desired key type.
* It must not contain any key material yet.
* \param[in] data Buffer containing the key material to parse and import.
* \param data_length Size of \p data in bytes.
*
* \retval PSA_SUCCESS
* \retval PSA_ERROR_INVALID_ARGUMENT
* \retval PSA_ERROR_NOT_SUPPORTED
* \retval PSA_ERROR_INSUFFICIENT_MEMORY
*/
psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot,
const uint8_t *data,
size_t data_length );
#endif /* PSA_CRYPTO_CORE_H */

View File

@ -0,0 +1,79 @@
/**
* \file psa_crypto_invasive.h
*
* \brief PSA cryptography module: invasive interfaces for test only.
*
* The interfaces in this file are intended for testing purposes only.
* They MUST NOT be made available to clients over IPC in integrations
* with isolation, and they SHOULD NOT be made available in library
* integrations except when building the library for testing.
*/
/*
* Copyright (C) 2018, 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)
*/
#ifndef PSA_CRYPTO_INVASIVE_H
#define PSA_CRYPTO_INVASIVE_H
#if defined(MBEDTLS_CONFIG_FILE)
#include MBEDTLS_CONFIG_FILE
#else
#include "mbedtls/config.h"
#endif
#include "psa/crypto.h"
#include "mbedtls/entropy.h"
/** \brief Configure entropy sources.
*
* This function may only be called before a call to psa_crypto_init(),
* or after a call to mbedtls_psa_crypto_free() and before any
* subsequent call to psa_crypto_init().
*
* This function is only intended for test purposes. The functionality
* it provides is also useful for system integrators, but
* system integrators should configure entropy drivers instead of
* breaking through to the Mbed TLS API.
*
* \param entropy_init Function to initialize the entropy context
* and set up the desired entropy sources.
* It is called by psa_crypto_init().
* By default this is mbedtls_entropy_init().
* This function cannot report failures directly.
* To indicate a failure, set the entropy context
* to a state where mbedtls_entropy_func() will
* return an error.
* \param entropy_free Function to free the entropy context
* and associated resources.
* It is called by mbedtls_psa_crypto_free().
* By default this is mbedtls_entropy_free().
*
* \retval PSA_SUCCESS
* Success.
* \retval PSA_ERROR_NOT_PERMITTED
* The caller does not have the permission to configure
* entropy sources.
* \retval PSA_ERROR_BAD_STATE
* The library has already been initialized.
*/
psa_status_t mbedtls_psa_crypto_configure_entropy_sources(
void (* entropy_init )( mbedtls_entropy_context *ctx ),
void (* entropy_free )( mbedtls_entropy_context *ctx ) );
#endif /* PSA_CRYPTO_INVASIVE_H */

View File

@ -0,0 +1,291 @@
/*
* PSA crypto layer on top of Mbed TLS crypto
*/
/* Copyright (C) 2018, 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_PSA_CRYPTO_C)
/*
* When MBEDTLS_PSA_CRYPTO_SPM is defined, the code is being built for SPM
* (Secure Partition Manager) integration which separates the code into two
* parts: NSPE (Non-Secure Processing Environment) and SPE (Secure Processing
* Environment). When building for the SPE, an additional header file should be
* included.
*/
#if defined(MBEDTLS_PSA_CRYPTO_SPM)
/*
* PSA_CRYPTO_SECURE means that this file is compiled for the SPE.
* Some headers will be affected by this flag.
*/
#define PSA_CRYPTO_SECURE 1
#include "crypto_spe.h"
#endif
#include "psa/crypto.h"
#include "psa_crypto_core.h"
#include "psa_crypto_slot_management.h"
#include "psa_crypto_storage.h"
#include <stdlib.h>
#include <string.h>
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#define mbedtls_calloc calloc
#define mbedtls_free free
#endif
#define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) )
typedef struct
{
psa_key_slot_t key_slots[PSA_KEY_SLOT_COUNT];
unsigned key_slots_initialized : 1;
} psa_global_data_t;
static psa_global_data_t global_data;
/* Access a key slot at the given handle. The handle of a key slot is
* the index of the slot in the global slot array, plus one so that handles
* start at 1 and not 0. */
psa_status_t psa_get_key_slot( psa_key_handle_t handle,
psa_key_slot_t **p_slot )
{
psa_key_slot_t *slot = NULL;
if( ! global_data.key_slots_initialized )
return( PSA_ERROR_BAD_STATE );
/* 0 is not a valid handle under any circumstance. This
* implementation provides slots number 1 to N where N is the
* number of available slots. */
if( handle == 0 || handle > ARRAY_LENGTH( global_data.key_slots ) )
return( PSA_ERROR_INVALID_HANDLE );
slot = &global_data.key_slots[handle - 1];
/* If the slot hasn't been allocated, the handle is invalid. */
if( ! slot->allocated )
return( PSA_ERROR_INVALID_HANDLE );
*p_slot = slot;
return( PSA_SUCCESS );
}
psa_status_t psa_initialize_key_slots( void )
{
/* Nothing to do: program startup and psa_wipe_all_key_slots() both
* guarantee that the key slots are initialized to all-zero, which
* means that all the key slots are in a valid, empty state. */
global_data.key_slots_initialized = 1;
return( PSA_SUCCESS );
}
void psa_wipe_all_key_slots( void )
{
psa_key_handle_t key;
for( key = 1; key <= PSA_KEY_SLOT_COUNT; key++ )
{
psa_key_slot_t *slot = &global_data.key_slots[key - 1];
(void) psa_wipe_key_slot( slot );
}
global_data.key_slots_initialized = 0;
}
/** Find a free key slot and mark it as in use.
*
* \param[out] handle On success, a slot number that is not in use. This
* value can be used as a handle to the slot.
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
*/
static psa_status_t psa_internal_allocate_key_slot( psa_key_handle_t *handle )
{
for( *handle = PSA_KEY_SLOT_COUNT; *handle != 0; --( *handle ) )
{
psa_key_slot_t *slot = &global_data.key_slots[*handle - 1];
if( ! slot->allocated )
{
slot->allocated = 1;
return( PSA_SUCCESS );
}
}
return( PSA_ERROR_INSUFFICIENT_MEMORY );
}
/** Wipe a key slot and mark it as available.
*
* This does not affect persistent storage.
*
* \param handle The handle to the key slot to release.
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \retval #PSA_ERROR_TAMPERING_DETECTED
*/
static psa_status_t psa_internal_release_key_slot( psa_key_handle_t handle )
{
psa_key_slot_t *slot;
psa_status_t status;
status = psa_get_key_slot( handle, &slot );
if( status != PSA_SUCCESS )
return( status );
return( psa_wipe_key_slot( slot ) );
}
psa_status_t psa_allocate_key( psa_key_handle_t *handle )
{
*handle = 0;
return( psa_internal_allocate_key_slot( handle ) );
}
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
static psa_status_t psa_load_persistent_key_into_slot( psa_key_slot_t *p_slot )
{
psa_status_t status = PSA_SUCCESS;
uint8_t *key_data = NULL;
size_t key_data_length = 0;
status = psa_load_persistent_key( p_slot->persistent_storage_id,
&( p_slot )->type,
&( p_slot )->policy, &key_data,
&key_data_length );
if( status != PSA_SUCCESS )
goto exit;
status = psa_import_key_into_slot( p_slot,
key_data, key_data_length );
exit:
psa_free_persistent_key_data( key_data, key_data_length );
return( status );
}
#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
/** Declare a slot as persistent and load it from storage.
*
* This function may only be called immediately after a successful call
* to psa_internal_allocate_key_slot().
*
* \param handle A handle to a key slot freshly allocated with
* psa_internal_allocate_key_slot().
*
* \retval #PSA_SUCCESS
* The slot content was loaded successfully.
* \retval #PSA_ERROR_EMPTY_SLOT
* There is no content for this slot in persistent storage.
* \retval #PSA_ERROR_INVALID_HANDLE
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \p id is not acceptable.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_STORAGE_FAILURE
*/
static psa_status_t psa_internal_make_key_persistent( psa_key_handle_t handle,
psa_key_id_t id )
{
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
psa_key_slot_t *slot;
psa_status_t status;
/* Reject id=0 because by general library conventions, 0 is an invalid
* value wherever possible. */
if( id == 0 )
return( PSA_ERROR_INVALID_ARGUMENT );
/* Reject high values because the file names are reserved for the
* library's internal use. */
if( id >= PSA_MAX_PERSISTENT_KEY_IDENTIFIER )
return( PSA_ERROR_INVALID_ARGUMENT );
status = psa_get_key_slot( handle, &slot );
if( status != PSA_SUCCESS )
return( status );
slot->lifetime = PSA_KEY_LIFETIME_PERSISTENT;
slot->persistent_storage_id = id;
status = psa_load_persistent_key_into_slot( slot );
return( status );
#else /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
(void) handle;
(void) id;
return( PSA_ERROR_NOT_SUPPORTED );
#endif /* !MBEDTLS_PSA_CRYPTO_STORAGE_C */
}
static psa_status_t persistent_key_setup( psa_key_lifetime_t lifetime,
psa_key_id_t id,
psa_key_handle_t *handle,
psa_status_t wanted_load_status )
{
psa_status_t status;
*handle = 0;
if( lifetime != PSA_KEY_LIFETIME_PERSISTENT )
return( PSA_ERROR_INVALID_ARGUMENT );
status = psa_internal_allocate_key_slot( handle );
if( status != PSA_SUCCESS )
return( status );
status = psa_internal_make_key_persistent( *handle, id );
if( status != wanted_load_status )
{
psa_internal_release_key_slot( *handle );
*handle = 0;
}
return( status );
}
psa_status_t psa_open_key( psa_key_lifetime_t lifetime,
psa_key_id_t id,
psa_key_handle_t *handle )
{
return( persistent_key_setup( lifetime, id, handle, PSA_SUCCESS ) );
}
psa_status_t psa_create_key( psa_key_lifetime_t lifetime,
psa_key_id_t id,
psa_key_handle_t *handle )
{
psa_status_t status;
status = persistent_key_setup( lifetime, id, handle,
PSA_ERROR_EMPTY_SLOT );
switch( status )
{
case PSA_SUCCESS: return( PSA_ERROR_OCCUPIED_SLOT );
case PSA_ERROR_EMPTY_SLOT: return( PSA_SUCCESS );
default: return( status );
}
}
psa_status_t psa_close_key( psa_key_handle_t handle )
{
return( psa_internal_release_key_slot( handle ) );
}
#endif /* MBEDTLS_PSA_CRYPTO_C */

View File

@ -0,0 +1,58 @@
/*
* PSA crypto layer on top of Mbed TLS crypto
*/
/* Copyright (C) 2018, 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)
*/
#ifndef PSA_CRYPTO_SLOT_MANAGEMENT_H
#define PSA_CRYPTO_SLOT_MANAGEMENT_H
/* Number of key slots (plus one because 0 is not used).
* The value is a compile-time constant for now, for simplicity. */
#define PSA_KEY_SLOT_COUNT 32
/** Access a key slot at the given handle.
*
* \param handle Key handle to query.
* \param[out] p_slot On success, `*p_slot` contains a pointer to the
* key slot in memory designated by \p handle.
*
* \retval PSA_SUCCESS
* Success: \p handle is a handle to `*p_slot`. Note that `*p_slot`
* may be empty or occupied.
* \retval PSA_ERROR_INVALID_HANDLE
* \p handle is out of range or is not in use.
* \retval PSA_ERROR_BAD_STATE
* The library has not been initialized.
*/
psa_status_t psa_get_key_slot( psa_key_handle_t handle,
psa_key_slot_t **p_slot );
/** Initialize the key slot structures.
*
* \retval PSA_SUCCESS
* Currently this function always succeeds.
*/
psa_status_t psa_initialize_key_slots( void );
/** Delete all data from key slots in memory.
*
* This does not affect persistent storage. */
void psa_wipe_all_key_slots( void );
#endif /* PSA_CRYPTO_SLOT_MANAGEMENT_H */

View File

@ -147,7 +147,7 @@ psa_status_t psa_parse_key_data_from_storage( const uint8_t *storage_data,
return( PSA_SUCCESS );
}
psa_status_t psa_save_persistent_key( const psa_key_slot_t key,
psa_status_t psa_save_persistent_key( const psa_key_id_t key,
const psa_key_type_t type,
const psa_key_policy_t *policy,
const uint8_t *data,
@ -185,7 +185,7 @@ void psa_free_persistent_key_data( uint8_t *key_data, size_t key_data_length )
mbedtls_free( key_data );
}
psa_status_t psa_load_persistent_key( psa_key_slot_t key,
psa_status_t psa_load_persistent_key( psa_key_id_t key,
psa_key_type_t *type,
psa_key_policy_t *policy,
uint8_t **data,

View File

@ -44,6 +44,23 @@ extern "C" {
* inadvertently store an obscene amount of data) */
#define PSA_CRYPTO_MAX_STORAGE_SIZE ( 30 * 1024 )
/** The maximum permitted persistent slot number.
*
* In Mbed Crypto 0.1.0b:
* - Using the file backend, all key ids are ok except 0.
* - Using the ITS backend, all key ids are ok except 0xFFFFFF52
* (#PSA_CRYPTO_ITS_RANDOM_SEED_UID) for which the file contains the
* device's random seed (if this feature is enabled).
* - Only key ids from 1 to #PSA_KEY_SLOT_COUNT are actually used.
*
* Since we need to preserve the random seed, avoid using that key slot.
* Reserve a whole range of key slots just in case something else comes up.
*
* This limitation will probably become moot when we implement client
* separation for key storage.
*/
#define PSA_MAX_PERSISTENT_KEY_IDENTIFIER 0xffff0000
/**
* \brief Format key data and metadata and save to a location for given key
* slot.
@ -56,20 +73,20 @@ extern "C" {
* already occupied non-persistent key, as well as validating the key data.
*
*
* \param key Slot number of the key to be stored. This must be a
* valid slot for a key of the chosen type. This should be
* an occupied key slot with an unoccupied corresponding
* storage location.
* \param key Persistent identifier of the key to be stored. This
* should be an unoccupied storage location.
* \param type Key type (a \c PSA_KEY_TYPE_XXX value).
* \param[in] policy The key policy to save.
* \param[in] data Buffer containing the key data.
* \param data_length The number of bytes that make up the key data.
*
* \retval PSA_SUCCESS
* \retval PSA_ERROR_INSUFFICIENT_MEMORY
* \retval PSA_ERROR_INSUFFICIENT_STORAGE
* \retval PSA_ERROR_STORAGE_FAILURE
* \retval PSA_ERROR_OCCUPIED_SLOT
*/
psa_status_t psa_save_persistent_key( const psa_key_slot_t key,
psa_status_t psa_save_persistent_key( const psa_key_id_t key,
const psa_key_type_t type,
const psa_key_policy_t *policy,
const uint8_t *data,
@ -87,10 +104,8 @@ psa_status_t psa_save_persistent_key( const psa_key_slot_t key,
* this function to zeroize and free this buffer, regardless of whether this
* function succeeds or fails.
*
* \param key Slot number whose content is to be loaded. This
* must be an unoccupied key slot with an occupied
* corresponding storage location. The key slot
* lifetime must be set to persistent.
* \param key Persistent identifier of the key to be loaded. This
* should be an occupied storage location.
* \param[out] type On success, the key type (a \c PSA_KEY_TYPE_XXX
* value).
* \param[out] policy On success, the key's policy.
@ -100,8 +115,9 @@ psa_status_t psa_save_persistent_key( const psa_key_slot_t key,
* \retval PSA_SUCCESS
* \retval PSA_ERROR_INSUFFICIENT_MEMORY
* \retval PSA_ERROR_STORAGE_FAILURE
* \retval PSA_ERROR_EMPTY_SLOT
*/
psa_status_t psa_load_persistent_key( psa_key_slot_t key,
psa_status_t psa_load_persistent_key( psa_key_id_t key,
psa_key_type_t *type,
psa_key_policy_t *policy,
uint8_t **data,
@ -110,16 +126,18 @@ psa_status_t psa_load_persistent_key( psa_key_slot_t key,
/**
* \brief Remove persistent data for the given key slot number.
*
* \param key Slot number whose content is to be removed
* \param key Persistent identifier of the key to remove
* from persistent storage.
*
* \retval PSA_SUCCESS
* The key was successfully removed,
* or the key did not exist.
* \retval PSA_ERROR_STORAGE_FAILURE
*/
psa_status_t psa_destroy_persistent_key( const psa_key_slot_t key );
psa_status_t psa_destroy_persistent_key( const psa_key_id_t key );
/**
* \brief Zeroizes and frees the given buffer.
* \brief Free the temporary buffer allocated by psa_load_persistent_key().
*
* This function must be called at some point after psa_load_persistent_key()
* to zeroize and free the memory allocated to the buffer in that function.

View File

@ -47,15 +47,16 @@ extern "C" {
* This function reads data from a storage backend and returns the data in a
* buffer.
*
* \param key Slot number whose content is to be loaded. This must
* be a key slot whose lifetime is set to persistent.
* \param[out] data Buffer where the data is to be written.
* \param data_size Size of the \c data buffer in bytes.
* \param key Persistent identifier of the key to be loaded. This
* should be an occupied storage location.
* \param[out] data Buffer where the data is to be written.
* \param data_size Size of the \c data buffer in bytes.
*
* \retval PSA_SUCCESS
* \retval PSA_ERROR_STORAGE_FAILURE
* \retval PSA_ERROR_EMPTY_SLOT
*/
psa_status_t psa_crypto_storage_load( const psa_key_slot_t key, uint8_t *data,
psa_status_t psa_crypto_storage_load( const psa_key_id_t key, uint8_t *data,
size_t data_size );
/**
@ -63,7 +64,8 @@ psa_status_t psa_crypto_storage_load( const psa_key_slot_t key, uint8_t *data,
*
* This function stores the given data buffer to a persistent storage.
*
* \param key Slot number whose content is to be stored.
* \param key Persistent identifier of the key to be stored. This
* should be an unoccupied storage location.
* \param[in] data Buffer containing the data to be stored.
* \param data_length The number of bytes
* that make up the data.
@ -71,8 +73,9 @@ psa_status_t psa_crypto_storage_load( const psa_key_slot_t key, uint8_t *data,
* \retval PSA_SUCCESS
* \retval PSA_ERROR_INSUFFICIENT_STORAGE
* \retval PSA_ERROR_STORAGE_FAILURE
* \retval PSA_ERROR_OCCUPIED_SLOT
*/
psa_status_t psa_crypto_storage_store( const psa_key_slot_t key,
psa_status_t psa_crypto_storage_store( const psa_key_id_t key,
const uint8_t *data,
size_t data_length );
@ -82,26 +85,26 @@ psa_status_t psa_crypto_storage_store( const psa_key_slot_t key,
* This function checks if any key data or metadata exists for the key slot in
* the persistent storage.
*
* \param key Slot number whose content is to be checked.
* \param key Persistent identifier to check.
*
* \retval 0
* No persistent data present for slot number
* \retval 1
* Persistent data present for slot number
*/
int psa_is_key_present_in_storage( const psa_key_slot_t key );
int psa_is_key_present_in_storage( const psa_key_id_t key );
/**
* \brief Get data length for given key slot number.
*
* \param key Slot number whose stored data length is to be obtained.
* \param[out] data_length The number of bytes
* that make up the data.
* \param key Persistent identifier whose stored data length
* is to be obtained.
* \param[out] data_length The number of bytes that make up the data.
*
* \retval PSA_SUCCESS
* \retval PSA_ERROR_STORAGE_FAILURE
*/
psa_status_t psa_crypto_storage_get_data_length( const psa_key_slot_t key,
psa_status_t psa_crypto_storage_get_data_length( const psa_key_id_t key,
size_t *data_length );

View File

@ -48,15 +48,16 @@
enum { MAX_LOCATION_LEN = sizeof(CRYPTO_STORAGE_FILE_LOCATION) + 40 };
static void key_slot_to_location( const psa_key_slot_t key,
char *location,
size_t location_size )
static void key_id_to_location( const psa_key_id_t key,
char *location,
size_t location_size )
{
mbedtls_snprintf( location, location_size,
CRYPTO_STORAGE_FILE_LOCATION "psa_key_slot_%d", key );
CRYPTO_STORAGE_FILE_LOCATION "psa_key_slot_%lu",
(unsigned long) key );
}
psa_status_t psa_crypto_storage_load( const psa_key_slot_t key, uint8_t *data,
psa_status_t psa_crypto_storage_load( const psa_key_id_t key, uint8_t *data,
size_t data_size )
{
psa_status_t status = PSA_SUCCESS;
@ -64,7 +65,7 @@ psa_status_t psa_crypto_storage_load( const psa_key_slot_t key, uint8_t *data,
size_t num_read;
char slot_location[MAX_LOCATION_LEN];
key_slot_to_location( key, slot_location, MAX_LOCATION_LEN );
key_id_to_location( key, slot_location, MAX_LOCATION_LEN );
file = fopen( slot_location, "rb" );
if( file == NULL )
{
@ -81,12 +82,12 @@ exit:
return( status );
}
int psa_is_key_present_in_storage( const psa_key_slot_t key )
int psa_is_key_present_in_storage( const psa_key_id_t key )
{
char slot_location[MAX_LOCATION_LEN];
FILE *file;
key_slot_to_location( key, slot_location, MAX_LOCATION_LEN );
key_id_to_location( key, slot_location, MAX_LOCATION_LEN );
file = fopen( slot_location, "r" );
if( file == NULL )
@ -99,7 +100,7 @@ int psa_is_key_present_in_storage( const psa_key_slot_t key )
return( 1 );
}
psa_status_t psa_crypto_storage_store( const psa_key_slot_t key,
psa_status_t psa_crypto_storage_store( const psa_key_id_t key,
const uint8_t *data,
size_t data_length )
{
@ -114,7 +115,7 @@ psa_status_t psa_crypto_storage_store( const psa_key_slot_t key,
* affect actual keys. */
const char *temp_location = CRYPTO_STORAGE_FILE_LOCATION "psa_key_slot_0";
key_slot_to_location( key, slot_location, MAX_LOCATION_LEN );
key_id_to_location( key, slot_location, MAX_LOCATION_LEN );
if( psa_is_key_present_in_storage( key ) == 1 )
return( PSA_ERROR_OCCUPIED_SLOT );
@ -154,12 +155,12 @@ exit:
return( status );
}
psa_status_t psa_destroy_persistent_key( const psa_key_slot_t key )
psa_status_t psa_destroy_persistent_key( const psa_key_id_t key )
{
FILE *file;
char slot_location[MAX_LOCATION_LEN];
key_slot_to_location( key, slot_location, MAX_LOCATION_LEN );
key_id_to_location( key, slot_location, MAX_LOCATION_LEN );
/* Only try remove the file if it exists */
file = fopen( slot_location, "rb" );
@ -173,7 +174,7 @@ psa_status_t psa_destroy_persistent_key( const psa_key_slot_t key )
return( PSA_SUCCESS );
}
psa_status_t psa_crypto_storage_get_data_length( const psa_key_slot_t key,
psa_status_t psa_crypto_storage_get_data_length( const psa_key_id_t key,
size_t *data_length )
{
psa_status_t status = PSA_SUCCESS;
@ -181,7 +182,7 @@ psa_status_t psa_crypto_storage_get_data_length( const psa_key_slot_t key,
long file_size;
char slot_location[MAX_LOCATION_LEN];
key_slot_to_location( key, slot_location, MAX_LOCATION_LEN );
key_id_to_location( key, slot_location, MAX_LOCATION_LEN );
file = fopen( slot_location, "rb" );
if( file == NULL )

View File

@ -68,12 +68,12 @@ static psa_status_t its_to_psa_error( psa_its_status_t ret )
}
}
static uint32_t psa_its_identifier_of_slot( psa_key_slot_t key )
static uint32_t psa_its_identifier_of_slot( psa_key_id_t key )
{
return( key );
}
psa_status_t psa_crypto_storage_load( const psa_key_slot_t key, uint8_t *data,
psa_status_t psa_crypto_storage_load( const psa_key_id_t key, uint8_t *data,
size_t data_size )
{
psa_its_status_t ret;
@ -92,7 +92,7 @@ psa_status_t psa_crypto_storage_load( const psa_key_slot_t key, uint8_t *data,
return( status );
}
int psa_is_key_present_in_storage( const psa_key_slot_t key )
int psa_is_key_present_in_storage( const psa_key_id_t key )
{
psa_its_status_t ret;
uint32_t data_identifier = psa_its_identifier_of_slot( key );
@ -105,7 +105,7 @@ int psa_is_key_present_in_storage( const psa_key_slot_t key )
return( 1 );
}
psa_status_t psa_crypto_storage_store( const psa_key_slot_t key,
psa_status_t psa_crypto_storage_store( const psa_key_id_t key,
const uint8_t *data,
size_t data_length )
{
@ -143,7 +143,7 @@ exit:
return( status );
}
psa_status_t psa_destroy_persistent_key( const psa_key_slot_t key )
psa_status_t psa_destroy_persistent_key( const psa_key_id_t key )
{
psa_its_status_t ret;
uint32_t data_identifier = psa_its_identifier_of_slot( key );
@ -163,7 +163,7 @@ psa_status_t psa_destroy_persistent_key( const psa_key_slot_t key )
return( PSA_SUCCESS );
}
psa_status_t psa_crypto_storage_get_data_length( const psa_key_slot_t key,
psa_status_t psa_crypto_storage_get_data_length( const psa_key_id_t key,
size_t *data_length )
{
psa_its_status_t ret;

View File

@ -85,6 +85,13 @@ struct psa_hash_operation_s
} ctx;
};
#define PSA_HASH_OPERATION_INIT {0, {0}}
static inline struct psa_hash_operation_s psa_hash_operation_init( void )
{
const struct psa_hash_operation_s v = PSA_HASH_OPERATION_INIT;
return( v );
}
#if defined(MBEDTLS_MD_C)
typedef struct
{
@ -116,6 +123,13 @@ struct psa_mac_operation_s
} ctx;
};
#define PSA_MAC_OPERATION_INIT {0, 0, 0, 0, 0, 0, 0, {0}}
static inline struct psa_mac_operation_s psa_mac_operation_init( void )
{
const struct psa_mac_operation_s v = PSA_MAC_OPERATION_INIT;
return( v );
}
struct psa_cipher_operation_s
{
psa_algorithm_t alg;
@ -126,10 +140,18 @@ struct psa_cipher_operation_s
uint8_t block_size;
union
{
unsigned dummy; /* Enable easier initializing of the union. */
mbedtls_cipher_context_t cipher;
} ctx;
};
#define PSA_CIPHER_OPERATION_INIT {0, 0, 0, 0, 0, 0, {0}}
static inline struct psa_cipher_operation_s psa_cipher_operation_init( void )
{
const struct psa_cipher_operation_s v = PSA_CIPHER_OPERATION_INIT;
return( v );
}
#if defined(MBEDTLS_MD_C)
typedef struct
{
@ -208,4 +230,11 @@ struct psa_key_policy_s
psa_algorithm_t alg;
};
#define PSA_KEY_POLICY_INIT {0, 0}
static inline struct psa_key_policy_s psa_key_policy_init( void )
{
const struct psa_key_policy_s v = PSA_KEY_POLICY_INIT;
return( v );
}
#endif /* PSA_CRYPTO_STRUCT_H */