1 /* Copyright (c) (2019-2022) Apple Inc. All rights reserved. 2 * 3 * corecrypto is licensed under Apple Inc.’s Internal Use License Agreement (which 4 * is contained in the License.txt file distributed with corecrypto) and only to 5 * people who accept that license. IMPORTANT: Any license rights granted to you by 6 * Apple Inc. (if any) are limited to internal use within your organization only on 7 * devices and computers you own or control, for the sole purpose of verifying the 8 * security characteristics and correct functioning of the Apple Software. You may 9 * not, directly or indirectly, redistribute the Apple Software or any portions thereof. 10 */ 11 12 #ifndef _CORECRYPTO_CCMODE_SIV_HMAC_H 13 #define _CORECRYPTO_CCMODE_SIV_HMAC_H 14 15 #include <corecrypto/cc.h> 16 #include <corecrypto/ccmode.h> 17 #include <corecrypto/ccmode_impl.h> 18 #include <corecrypto/ccdigest.h> 19 #include <corecrypto/cchmac.h> 20 #include <corecrypto/ccsha2.h> 21 22 #define ccsiv_hmac_ctx_decl(_size_, _name_) cc_ctx_decl_vla(ccsiv_hmac_ctx, _size_, _name_) 23 #define ccsiv_hmac_ctx_clear(_size_, _name_) cc_clear(_size_, _name_) 24 25 /*! 26 @function ccsiv_hmac_context_size 27 @abstract Return size of context 28 29 @param mode Descriptor for the mode 30 */ 31 size_t ccsiv_hmac_context_size(const struct ccmode_siv_hmac *mode); 32 33 /*! 34 @function ccsiv_hmac_block_size 35 @abstract Return size of context 36 37 @param mode Descriptor for the mode 38 */ 39 size_t ccsiv_hmac_block_size(const struct ccmode_siv_hmac *mode); 40 41 /*! 42 @function ccsiv_hmac_ciphertext_size 43 @abstract Return size of Ciphertext (which is the ciphertext and corresponding tag) given the mode and plaintext length 44 45 @param ctx Current siv_hmac context that has been previously initialized 46 @param plaintext_size Size of the plaintext 47 48 @discussion returns the length of the aead ciphertext that the context will generate which includes both the encrypted plaintext 49 and tag. 50 */ 51 size_t ccsiv_hmac_ciphertext_size(ccsiv_hmac_ctx *ctx, size_t plaintext_size); 52 53 /*! 54 @function ccsiv_hmac_plaintext_size 55 @abstract Return size of plaintext given a ciphertext length and mode. 56 57 @param ctx Current siv_hmac context that has been previously initialized 58 @param ciphertext_size Size of the ciphertext (which includes the tag) 59 60 @discussion returns the length of the plaintext which results from the decryption of a ciphertext of the corresponding size (here ciphertext size includes the tag). 61 */ 62 size_t ccsiv_hmac_plaintext_size(ccsiv_hmac_ctx *ctx, size_t ciphertext_size); 63 64 /*! 65 @function ccsiv_hmac_init 66 @abstract Initialize a context for siv_hmac with an associated mode, given key and specifying output tag size. 67 68 @param mode Descriptor for the mode 69 @param ctx Alocated context to be intialized 70 @param key_byte_len Length of the key: Supported key sizes are 32, 48, 64 bytes 71 @param key key for siv_hmac 72 @param tag_size The length of the output tag requested. Must be at least 20 bytes, and can be as large as the 73 associated digest's output 74 75 @discussion In order to compute HMAC_SIV_Enc_k(a1,...,am, n, x) where ai is the ith piece of associated data, n is a nonce and x 76 is a plaintext, we first initialize the context with this call, and then use it to call ccsiv_hmac_aad for each ai, followed by 77 ccsiv_hmac_set_nonce for nonce n, and finally a call to ccsiv_hmac_crypt for the plaintext x. Note the order of the calls to aad, 78 nonce and then crypt is critical. If a second encryption is needed then a call to ccsiv_hmac_reset can be used to reset state, 79 and begin again. 80 */ 81 int ccsiv_hmac_init(const struct ccmode_siv_hmac *mode, ccsiv_hmac_ctx *ctx, size_t key_byte_len, const uint8_t *key, size_t tag_size); 82 83 /*! 84 @function ccsiv_hmac_aad 85 @abstract Add the next piece of associated data to the hmac_siv's computation of the tag. Note this call is optional and no 86 associated data needs to be provided. Multiple pieces of associated data can be provided by multiple calls to this 87 function. Each input is regarded as a separate piece of associated data, and the mac is NOT simply computed on the 88 concatenation of all of the associated data inputs. Therefore on decryption the same inputs must be provided in 89 the same order. 90 91 @param mode Descriptor for the mode 92 @param ctx Intialized ctx 93 @param nbytes Length of the current associated data being added 94 @param in Associated data to be authenticated. 95 96 @discussion Adds the associated data given by in to the computation of the tag in the associated data. 97 */ 98 int ccsiv_hmac_aad(const struct ccmode_siv_hmac *mode, ccsiv_hmac_ctx *ctx, size_t nbytes, const uint8_t *in); 99 100 /*! 101 @function ccsiv_hmac_nonce 102 @abstract Add the nonce to the hmac_siv's computation of the the tag. Changes the internal state of the context 103 so that after the call only a crypt or reset call is permitted. 104 @param mode Descriptor for the mode 105 @param ctx Intialized ctx 106 @param nbytes Length of the current nonce data being added 107 @param in Nonce data to be authenticated. 108 109 @discussion The nonce is a special form of authenticated data. If provided ( a call to hmac_nonce is optional) it allows 110 randomization of the ciphertext (preventing deterministic encryption). While the length of the nonce is not limited, the 111 amount of entropy that can be provided is limited by the number of bits in the block of the associated block-cipher in mode. 112 */ 113 int ccsiv_hmac_set_nonce(const struct ccmode_siv_hmac *mode, ccsiv_hmac_ctx *ctx, size_t nbytes, const uint8_t *in); 114 115 /*! 116 @function ccsiv_hmac_crypt 117 @abstract Depending on whether mode has been setup to encrypt or decrypt, this function 118 1) Encrypts the plaintext given as input in, and provides the ciphertext (which is a concatenation of the tag 119 followed by the encrypted plaintext) as output out. 2) Decrypts plaintext using the input ciphertext at in (which again is the 120 tag, followed by encrypted plaintext), and then verifies that the computer tag and provided tags match. 121 @param mode Descriptor for the mode 122 @param ctx Intialized ctx 123 @param nbytes Case 1) Length of the current plaintext 124 Case 2) Length of the current ciphertext (tag length + plaintext length) 125 @param in Case 1) Plaintext 126 Case 2) Ciphertext 127 @discussion This function is only called once. If one wishes to compute another (en)/(de)cryption, one resets the state with 128 ccsiv_hmac_reset, and then begins the process again. There is no way to stream large plaintext/ciphertext inputs into the 129 function. 130 @param out Case1) Tag+ Ciphertext (buffer should be already allocated and of length tag + plaintext length) 131 Case 2) Plaintext (buffer should be already allocated and of length ciphertext - tag length 132 133 In the case of a decryption, if there is a failure in verifying the computed tag against the provided tag (embedded int he ciphertext), then a decryption/verification 134 failure is returned, and any internally computed plaintexts and tags are zeroed out. 135 Lastly the contexts internal state is reset, so that a new decryption/encryption can be commenced. 136 */ 137 int ccsiv_hmac_crypt(const struct ccmode_siv_hmac *mode, ccsiv_hmac_ctx *ctx, size_t nbytes, const uint8_t *in, uint8_t *out); 138 139 /*! 140 @function ccsiv_hmac_reset 141 @abstract Resets the state of the siv_hamc ctx, maintaining the key, but preparing the 142 ctx to preform a new Associated Data Authenticated (En)/(De)cryption. 143 @param mode Descriptor for the mode 144 @param ctx Intialized ctx 145 */ 146 int ccsiv_hmac_reset(const struct ccmode_siv_hmac *mode, ccsiv_hmac_ctx *ctx); 147 148 /*! 149 @function ccsiv_hmac_one_shot 150 @abstract A simplified but more constrained way of performing an AEAD SIV HMAC (en)/(de)cryption. It is limited because only 151 one piece of associated data may be provided. 152 @param mode Descriptor for the mode 153 @param key_len Length of the key: Supported key sizes are 32, 48, 64 bytes 154 @param key key for siv_hmac 155 @param tag_length The length of the tag to produce or accept as input. Must be at least 20 156 bytes, and can be as large as the hmac's digest's output 157 @param nonce_nbytes Length of the current nonce data being added 158 @param nonce Nonce data to be authenticated. 159 @param adata_nbytes Length of the associated data. 160 @param adata Associated data to be authenticated. 161 @param in_nbytes Length of either the plaintext (for encryption) or ciphertext (for decryption) 162 @param in plaintext or ciphertext. Note that the ciphertext includes a tag of length tag_length prepended to it. 163 @param out Buffer to hold ciphertext/plaintext. (Note Ciphertext is of size plaintext length + tag_length and plaintext is of length ciphertext - tag_length.) 164 */ 165 166 // One shot AEAD with only one input for adata, and a nonce. 167 int ccsiv_hmac_one_shot(const struct ccmode_siv_hmac *mode, 168 size_t key_len, 169 const uint8_t *key, 170 size_t tag_length, 171 unsigned nonce_nbytes, 172 const uint8_t *nonce, 173 unsigned adata_nbytes, 174 const uint8_t *adata, 175 size_t in_nbytes, 176 const uint8_t *in, 177 uint8_t *out); 178 179 #endif /* _CORECRYPTO_CCMODE_SIV_HMAC_H */ 180