| // 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_ |