| // Copyright lowRISC contributors. | |
| // Licensed under the Apache License, Version 2.0, see LICENSE for details. | |
| // SPDX-License-Identifier: Apache-2.0 | |
| #ifndef OPENTITAN_SW_DEVICE_LIB_CRYPTO_INCLUDE_AES_H_ | |
| #define OPENTITAN_SW_DEVICE_LIB_CRYPTO_INCLUDE_AES_H_ | |
| /** | |
| * @file | |
| * @brief AES operations for the OpenTitan cryptography library. | |
| */ | |
| #ifdef __cplusplus | |
| extern "C" { | |
| #endif // __cplusplus | |
| /** | |
| * Enum to denote the AES-GCM tag length. | |
| * | |
| * Values are hardened. | |
| */ | |
| typedef enum aead_gcm_tag_len { | |
| // Tag length 128 bits. | |
| kAeadGcmTagLen128 = 0xb9ab, | |
| // Tag length 120 bits. | |
| kAeadGcmTagLen120 = 0xae53, | |
| // Tag length 112 bits. | |
| kAeadGcmTagLen112 = 0x175d, | |
| // Tag length 104 bits. | |
| kAeadGcmTagLen104 = 0x68fc, | |
| // Tag length 96 bits. | |
| kAeadGcmTagLen96 = 0x7686, | |
| // Tag length 64 bits. | |
| kAeadGcmTagLen64 = 0xc6a9, | |
| // Tag length 32 bits. | |
| kAeadGcmTagLen32 = 0x4b37, | |
| } aead_gcm_tag_len_t; | |
| /** | |
| * Enum to define AES mode of operation. | |
| * | |
| * Values are hardened. | |
| */ | |
| typedef enum block_cipher_mode { | |
| // AES ECB mode (electronic codebook mode). | |
| kBlockCipherModeEcb = 0x7cae, | |
| // AES CBC mode (cipher block chaining mode). | |
| kBlockCipherModeCbc = 0x9736, | |
| // AES CFB mode (cipher feedback mode). | |
| kBlockCipherModeCfb = 0xe378, | |
| // AES OFB mode (output feedback mode). | |
| kBlockCipherModeOfb = 0x9cdd, | |
| // AES CTR mode (counter mode). | |
| kBlockCipherModeCtr = 0x4a1f, | |
| } block_cipher_mode_t; | |
| /** | |
| * Enum to define AES operation to be performed. | |
| * | |
| * Values are hardened. | |
| */ | |
| typedef enum aes_operation { | |
| // AES operation mode encrypt. | |
| kAesOperationEncrypt = 0xdea9, | |
| // AES operation mode decrypt. | |
| kAesOperationDecrypt = 0x5d5a, | |
| } aes_operation_t; | |
| /** | |
| * Enum to define padding scheme for AES data. | |
| * | |
| * Values are hardened. | |
| */ | |
| typedef enum aes_padding { | |
| // Pads with value same as the number of padding bytes. | |
| kAesPaddingPkcs7 = 0xce99, | |
| // Pads with 0x80 (10000000), followed by zero bytes. | |
| kAesPaddingIso9797M2 = 0xb377, | |
| // Pads with 0x00 bytes. | |
| kAesPaddingIso9797M1 = 0x49eb, | |
| // Pads with random bytes, last byte is no. of padded bytes. | |
| kAesPaddingRandom = 0x746c, | |
| // Pads with 0x00 bytes, last byte is no. of padded bytes. | |
| kAesPaddingX923 = 0xed32, | |
| // Add no padding. | |
| kAesPaddingNull = 0x259f, | |
| } aes_padding_t; | |
| /** | |
| * Context for GCM GHASH operation. | |
| * | |
| * Representation is internal to the hmac implementation; initialize | |
| * with #otcrypto_gcm_ghash_init. | |
| */ | |
| typedef struct gcm_ghash_context gcm_ghash_context_t; | |
| /** | |
| * Generates a new AES key. | |
| * | |
| * The caller should allocate and partially populate the blinded | |
| * key struct, including populating the key configuration and | |
| * allocating space for the keyblob. The caller should indicate | |
| * the length of the allocated keyblob; this function will | |
| * return an error if the keyblob length does not match | |
| * expectations. For hardware-backed keys, the keyblob length is 0 | |
| * and the keyblob pointer may be `NULL`. For non-hardware-backed keys, | |
| * the keyblob should be twice the length of the key. The value in | |
| * the `checksum` field of the blinded key struct will be populated | |
| * by the key generation function. | |
| * | |
| * @param[out] key Destination blinded key struct. | |
| * @return The result of the cipher operation. | |
| */ | |
| crypto_status_t otcrypto_aes_keygen(crypto_blinded_key_t *key); | |
| /** | |
| * Performs the AES operation. | |
| * | |
| * The input data in the `cipher_input` is first padded using the | |
| * `aes_padding` scheme and the output is copied to `cipher_output`. | |
| * | |
| * The caller should allocate space for the `cipher_output` buffer, | |
| * (same length as input, rounded up to the next full block), and | |
| * set the length of expected output in the `len` field of the | |
| * output. If the user-set length and the output length do not | |
| * match, an error message will be returned. | |
| * | |
| * @param key Pointer to the blinded key struct with key shares. | |
| * @param iv Initialization vector, used for CBC, CFB, OFB, CTR modes. | |
| * @param aes_mode Required AES mode of operation. | |
| * @param aes_operation Required AES operation (encrypt or decrypt). | |
| * @param cipher_input Input data to be ciphered. | |
| * @param aes_padding Padding scheme to be used for the data. | |
| * @param[out] cipher_output Output data after cipher operation. | |
| * @return The result of the cipher operation. | |
| */ | |
| crypto_status_t otcrypto_aes(const crypto_blinded_key_t *key, | |
| crypto_uint8_buf_t iv, | |
| block_cipher_mode_t aes_mode, | |
| aes_operation_t aes_operation, | |
| crypto_const_uint8_buf_t cipher_input, | |
| aes_padding_t aes_padding, | |
| crypto_uint8_buf_t *cipher_output); | |
| /** | |
| * Performs the AES-GCM authenticated encryption operation. | |
| * | |
| * This function encrypts the input `plaintext` to produce an | |
| * output `ciphertext`. Together it generates an authentication | |
| * tag `auth_tag` on the ciphered data and any non-confidential | |
| * additional authenticated data `aad`. | |
| * | |
| * The caller should allocate space for the `ciphertext` buffer, | |
| * (same length as input), `auth_tag` buffer (same as tag_len), and | |
| * set the length of expected outputs in the `len` field of | |
| * `ciphertext` and `auth_tag`. If the user-set length and the output | |
| * length does not match, an error message will be returned. | |
| * | |
| * @param key Pointer to the blinded gcm-key struct. | |
| * @param plaintext Input data to be encrypted and authenticated. | |
| * @param iv Initialization vector for the encryption function. | |
| * @param aad Additional authenticated data. | |
| * @param tag_len Length of authentication tag to be generated. | |
| * @param[out] ciphertext Encrypted output data, same length as input data. | |
| * @param[out] auth_tag Generated authentication tag. | |
| * @return Result of the authenticated encryption. | |
| * operation | |
| */ | |
| crypto_status_t otcrypto_aes_encrypt_gcm( | |
| const crypto_blinded_key_t *key, crypto_const_uint8_buf_t plaintext, | |
| crypto_uint8_buf_t iv, crypto_uint8_buf_t aad, aead_gcm_tag_len_t tag_len, | |
| crypto_uint8_buf_t *ciphertext, crypto_uint8_buf_t *auth_tag); | |
| /** | |
| * Performs the AES-GCM authenticated decryption operation. | |
| * | |
| * This function first verifies if the authentication tag `auth_tag` | |
| * matches the internally generated tag. Upon verification, the | |
| * function decrypts the input `ciphertext` to get a `plaintext data. | |
| * | |
| * The caller should allocate space for the `plaintext` buffer, | |
| * (same length as ciphertext), and set the length of expected output | |
| * in the `len` field of `plaintext`. If the user-set length and the | |
| * output length does not match, an error message will be returned. | |
| * | |
| * @param key Pointer to the blinded gcm-key struct. | |
| * @param ciphertext Input data to be decrypted. | |
| * @param iv Initialization vector for the decryption function. | |
| * @param aad Additional authenticated data. | |
| * @param auth_tag Authentication tag to be verified. | |
| * @param[out] plaintext Decrypted plaintext data, same len as input data. | |
| * @return Result of the authenticated decryption. | |
| * operation | |
| */ | |
| crypto_status_t otcrypto_aes_decrypt_gcm(const crypto_blinded_key_t *key, | |
| crypto_const_uint8_buf_t ciphertext, | |
| crypto_uint8_buf_t iv, | |
| crypto_uint8_buf_t aad, | |
| crypto_uint8_buf_t auth_tag, | |
| crypto_uint8_buf_t *plaintext); | |
| /** | |
| * Internal GHASH operation of Galois Counter Mode (GCM). | |
| * | |
| * GHASH is an operation internal to GCM. It can be used to create | |
| * custom implementations that do not adhere to the AES-GCM encryption | |
| * and decryption API provided here. However, custom GCM constructs | |
| * can be dangerous; for most use cases, prefer the provided | |
| * encryption and decryption operations. | |
| * | |
| * This function initializes the GHASH context and must be called | |
| * to create a context object. | |
| * | |
| * @param hash_subkey Hash subkey (H), 16 bytes. | |
| * @param[out] ctx Output GHASH context object, caller-allocated. | |
| * @return Result of the operation. | |
| */ | |
| crypto_status_t otcrypto_gcm_ghash_init(const crypto_blinded_key_t *hash_subkey, | |
| gcm_ghash_context_t *ctx); | |
| /** | |
| * Internal GHASH operation of Galois Counter Mode (GCM). | |
| * | |
| * GHASH is an operation internal to GCM. It can be used to create | |
| * custom implementations that do not adhere to the AES-GCM encryption | |
| * and decryption API provided here. However, custom GCM constructs | |
| * can be dangerous; for most use cases, prefer the provided | |
| * encryption and decryption operations. | |
| * | |
| * This operation adds the input buffer to the message that will | |
| * be hashed and updates the GHASH context. If the input length is | |
| * not a multiple of 128 bits, it will be right-padded with zeros. | |
| * The input length must not be zero. | |
| * | |
| * @param ctx GHASH context object. | |
| * @param input Input buffer. | |
| * @return Result of the operation. | |
| */ | |
| crypto_status_t otcrypto_gcm_ghash_update(gcm_ghash_context_t *ctx, | |
| crypto_const_uint8_buf_t input); | |
| /** | |
| * Internal GHASH operation of Galois Counter Mode (GCM). | |
| * | |
| * GHASH is an operation internal to GCM. It can be used to create | |
| * custom implementations that do not adhere to the AES-GCM encryption | |
| * and decryption API provided here. However, custom GCM constructs | |
| * can be dangerous; for most use cases, prefer the provided | |
| * encryption and decryption operations. | |
| * | |
| * This operation signals that all input has been provided and | |
| * extracts the digest from the GHASH context. The digest buffer must | |
| * be 16 bytes. | |
| * | |
| * @param ctx GHASH context object. | |
| * @param[out] digest Output buffer for digest, 16 bytes. | |
| * @return Result of the operation. | |
| */ | |
| crypto_status_t otcrypto_gcm_ghash_final(gcm_ghash_context_t *ctx, | |
| crypto_uint8_buf_t digest); | |
| /** | |
| * Internal AES-GCTR operation of AES Galois Counter Mode (AES-GCM). | |
| * | |
| * GCTR is an operation internal to AES-GCM and is based on AES-CTR. | |
| * It can be used to create custom implementations that do not adhere | |
| * to the AES-GCM encryption and decryption API provided here. | |
| * However, custom GCM constructs can be dangerous; for most use | |
| * cases, prefer the provided encryption and decryption operations. | |
| * | |
| * The caller-allocated output buffer must be the same length as the | |
| * input. | |
| * | |
| * @param key AES key for the GCTR operation. | |
| * @param input Input buffer. | |
| * @param[out] output Output buffer (same length as input). | |
| * @return Result of the operation. | |
| */ | |
| crypto_status_t otcrypto_aes_gcm_gctr(const crypto_blinded_key_t *key, | |
| crypto_const_uint8_buf_t input, | |
| crypto_uint8_buf_t output); | |
| /** | |
| * Performs the AES-KWP authenticated encryption operation. | |
| * | |
| * This encrypt function takes an input key `key_to_wrap` and using | |
| * the encryption key `key_kek` outputs a wrapped key `wrapped_key`. | |
| * | |
| * The caller should allocate space for the `wrapped_key` buffer, | |
| * (same len as `key_to_wrap`), and set the length of expected output | |
| * in the `len` field of `wrapped_key`. If the user-set length and the | |
| * output length does not match, an error message will be returned. | |
| * | |
| * @param key_to_wrap Pointer to the blinded key to be wrapped. | |
| * @param key_kek Input Pointer to the blinded encryption key. | |
| * @param[out] wrapped_key Pointer to the output wrapped key. | |
| * @return Result of the aes-kwp encrypt operation. | |
| */ | |
| crypto_status_t otcrypto_aes_kwp_encrypt( | |
| const crypto_blinded_key_t *key_to_wrap, | |
| const crypto_blinded_key_t *key_kek, crypto_uint8_buf_t *wrapped_key); | |
| /** | |
| * Performs the AES-KWP authenticated decryption operation. | |
| * | |
| * This decrypt function takes a wrapped key `wrapped_key` and using | |
| * encryption key `key_kek` outputs an unwrapped key `unwrapped_key`. | |
| * | |
| * @param wrapped_key Pointer to the input wrapped key. | |
| * @param key_kek Input Pointer to the blinded encryption key. | |
| * @param[out] unwrapped_key Pointer to the output unwrapped key struct. | |
| * @return Result of the aes-kwp decrypt operation. | |
| */ | |
| crypto_status_t otcrypto_aes_kwp_decrypt(crypto_const_uint8_buf_t wrapped_key, | |
| const crypto_blinded_key_t *key_kek, | |
| crypto_blinded_key_t *unwrapped_key); | |
| #ifdef __cplusplus | |
| } // extern "C" | |
| #endif // __cplusplus | |
| #endif // OPENTITAN_SW_DEVICE_LIB_CRYPTO_INCLUDE_AES_H_ |