]> git.saurik.com Git - apple/xnu.git/blob - EXTERNAL_HEADERS/corecrypto/ccmode_siv_hmac.h
xnu-6153.41.3.tar.gz
[apple/xnu.git] / EXTERNAL_HEADERS / corecrypto / ccmode_siv_hmac.h
1 //
2 // ccmode_siv_hmac.h
3 // corecrypto
4 //
5 // Created by Apple on 12/10/18.
6 //
7
8 #ifndef ccmode_siv_hmac_h
9 #define ccmode_siv_hmac_h
10
11 #include <corecrypto/cc.h>
12 #include <corecrypto/ccmode.h>
13 #include <corecrypto/ccmode_impl.h>
14 #include <corecrypto/ccdigest.h>
15 #include <corecrypto/cchmac.h>
16 #include <corecrypto/ccsha2.h>
17
18 /* This provides an implementation of SIV using AES CTR mode with HMAC as the MAC,
19 allowing for a tagging mechanism with collision resistant tags. This is a modification of the
20 standard specified in https://tools.ietf.org/html/rfc5297
21 also in http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/siv/siv.pdf
22 Counter Mode where IV is based on HMAC.
23 */
24
25 cc_aligned_struct(16) ccsiv_hmac_ctx;
26
27 struct ccmode_siv_hmac {
28 size_t size; /* first argument to ccsiv_hmac_ctx_decl(). */
29 size_t block_size;
30
31 int (*init)(const struct ccmode_siv_hmac *sivhmac,
32 ccsiv_hmac_ctx *ctx,
33 size_t key_len,
34 const uint8_t *key,
35 const size_t tag_size);
36 int (*set_nonce)(ccsiv_hmac_ctx *ctx, size_t nbytes, const uint8_t *in);
37 int (*auth)(ccsiv_hmac_ctx *ctx, size_t nbytes, const uint8_t *in);
38 int (*crypt)(ccsiv_hmac_ctx *ctx, size_t nbytes, const uint8_t *in, uint8_t *out);
39 int (*reset)(ccsiv_hmac_ctx *ctx);
40 const struct ccdigest_info *hmac_digest; // Digest to be used in HMAC;
41 const struct ccmode_ctr *ctr;
42 };
43
44 #define ccsiv_hmac_ctx_decl(_size_, _name_) cc_ctx_decl(ccsiv_hmac_ctx, _size_, _name_)
45 #define ccsiv_hmac_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
46
47 /*!
48 @function ccsiv_hmac_context_size
49 @abstract Return size of context
50
51 @param mode Descriptor for the mode
52 */
53 CC_INLINE size_t ccsiv_hmac_context_size(const struct ccmode_siv_hmac *mode)
54 {
55 return mode->size;
56 }
57
58 /*!
59 @function ccsiv_hmac_block_size
60 @abstract Return size of context
61
62 @param mode Descriptor for the mode
63 */
64 CC_INLINE size_t ccsiv_hmac_block_size(const struct ccmode_siv_hmac *mode)
65 {
66 return mode->block_size;
67 }
68
69 /*!
70 @function ccsiv_hmac_ciphertext_size
71 @abstract Return size of Ciphertext (which is the ciphertext and corresponding tag) given the mode and plaintext length
72
73 @param ctx Current siv_hmac context that has been previously initialized
74 @param plaintext_size Size of the plaintext
75
76 @discussion returns the length of the aead ciphertext that the context will generate which includes both the encrypted plaintext
77 and tag.
78 */
79 size_t ccsiv_hmac_ciphertext_size(ccsiv_hmac_ctx *ctx, size_t plaintext_size);
80
81 /*!
82 @function ccsiv_hmac_plaintext_size
83 @abstract Return size of plaintext given a ciphertext length and mode.
84
85 @param ctx Current siv_hmac context that has been previously initialized
86 @param ciphertext_size Size of the ciphertext
87
88 @discussion returns the length of the aead ciphertext which is both the encrypted plaintext and tag length together.
89 */
90 size_t ccsiv_hmac_plaintext_size(ccsiv_hmac_ctx *ctx, size_t ciphertext_size);
91
92 /*!
93 @function ccsiv_hmac_init
94 @abstract Initialize a context for siv_hmac with an associated mode, given key and specifying output tag size.
95
96 @param mode Descriptor for the mode
97 @param ctx Alocated context to be intialized
98 @param key_byte_len Length of the key: Supported key sizes are 32, 48, 64 bytes
99 @param key key for siv_hmac
100 @param tag_size The length of the output tag requested. Must be at least 20 bytes, and can be as larged as the
101 associated digest's output
102
103 @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
104 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
105 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,
106 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,
107 and begin again.
108 */
109 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);
110
111 /*!
112 @function ccsiv_hmac_aad
113 @abstract Add the next piece of associated data to the hmac_siv's computation of the tag. Note this call is optional and no
114 associated data needs to be provided. Multiple pieces of associated data can be provided by multiple calls to this
115 function. Each input is regarded as a seperate piece of associated data, and the mac is NOT simply computed on the
116 concatenation of all of the associated data inputs. Therefore on decryption the same inputs must be prodivded and in
117 the same order.
118
119 @param mode Descriptor for the mode
120 @param ctx Intialized ctx
121 @param nbytes Length of the current associated data being added
122 @param in Associated data to be authenticated.
123
124 @discussion Adds the associated data given by in to the computation of the tag in the associated data.
125 */
126 int ccsiv_hmac_aad(const struct ccmode_siv_hmac *mode, ccsiv_hmac_ctx *ctx, size_t nbytes, const uint8_t *in);
127
128 /*!
129 @function ccsiv_hmac_nonce
130 @abstract Add the nonce to the hmac_siv's computation of the the tag. Changes the internal state of the context
131 so that after the call only a crypt or reset call is permitted.
132 @param mode Descriptor for the mode
133 @param ctx Intialized ctx
134 @param nbytes Length of the current nonce data being added
135 @param in Nonce data to be authenticated.
136
137 @discussion The nonce is a special form of authenticated data. If provided ( a call to hmac_nonce is optional) it allows
138 randomization of the of ciphertext (preventing deterministic encryption). While the length of the nonce is not limimited, the
139 amount of entropy that can be provided is limited by the number of bits in the block of the associated block-cipher in mode.
140 */
141 int ccsiv_hmac_set_nonce(const struct ccmode_siv_hmac *mode, ccsiv_hmac_ctx *ctx, size_t nbytes, const uint8_t *in);
142
143 /*!
144 @function ccsiv_hmac_crypt
145 @abstract Depending on whether mode has been setup to encrypt or decrypt, this function
146 1) Encrypts the plaintext given as input in, and provides the ciphertext (which is a concatenation of the tag
147 followed by the encrypted plaintext) as output out. 2) Decrypts plaintext using the input ciphertext at in (which again is the
148 tag, followed by encrypted plaintext), and then verifies that the computer tag and provided tags match.
149 @param mode Descriptor for the mode
150 @param ctx Intialized ctx
151 @param nbytes Case 1) Length of the current plaintext
152 Case 2) Length of the current ciphertext (tag length + plaintext length)
153 @param in Case 1) Plaintext
154 Case 2) Ciphertext
155 @discussion This function is only called once. If one wishes to compute another (en)/(de)cryption, one resets the state with
156 ccsiv_hmac_reset, and then begins the process again. There is no way to stream large plaintext/ciphertext inputs into the
157 function.
158
159 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
160 failure is returned, and any internally computed plaintexts and tags are zeroed out.
161 Lastly the contexts internal state is reset, so that a new decryption/encryption can be commenced.
162 */
163 int ccsiv_hmac_crypt(const struct ccmode_siv_hmac *mode, ccsiv_hmac_ctx *ctx, size_t nbytes, const uint8_t *in, uint8_t *out);
164
165 /*!
166 @function ccsiv_hmac_reset
167 @abstract Resets the state of the siv_hamc ctx, maintaing the key, but preparing the
168 ctx to preform a new Associated Data Authenticated (En)/(De)cryption.
169 @param mode Descriptor for the mode
170 @param ctx Intialized ctx
171 */
172 int ccsiv_hmac_reset(const struct ccmode_siv_hmac *mode, ccsiv_hmac_ctx *ctx);
173
174 /*!
175 @function ccsiv_hmac_one_shot
176 @abstract A simplified but more constrained way of performing an AEAD SIV HMAC (en)/(de)cryption. It is limited because only
177 one piece of associated data may be provided.
178 @param mode Descriptor for the mode
179 @param key_len Length of the key: Supported key sizes are 32, 48, 64 bytes
180 @param key key for siv_hmac
181 @param tag_length The length of the tag to produce or accept as input. Must be at least 20
182 bytes, and can be as large as the hmac's digest's output
183 @param nonce_nbytes Length of the current nonce data being added
184 @param nonce Nonce data to be authenticated.
185 @param adata_nbytes Length of the associated data.
186 @param adata Associated data to be authenticated.
187 @param in_nbytes Length of either the plaintext (for encryption) or ciphertext (for decryption)
188 @param in plaintext or ciphertext. Note that the ciphertext includes a tag of length tag_length prepended to
189 it.
190 */
191
192 // One shot AEAD with only one input for adata, and a nonce.
193 int ccsiv_hmac_one_shot(const struct ccmode_siv_hmac *mode,
194 size_t key_len,
195 const uint8_t *key,
196 size_t tag_length,
197 unsigned nonce_nbytes,
198 const uint8_t *nonce,
199 unsigned adata_nbytes,
200 const uint8_t *adata,
201 size_t in_nbytes,
202 const uint8_t *in,
203 uint8_t *out);
204
205 #endif /* ccmode_siv_hmac_h */