1 /* Copyright (c) (2016,2017,2018,2019) 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_CCCHACHA20POLY1305_H_ 13 #define _CORECRYPTO_CCCHACHA20POLY1305_H_ 14 15 #include <stdbool.h> 16 #include <stddef.h> 17 #include <stdint.h> 18 19 #define CCCHACHA20_KEY_NBYTES 32 20 #define CCCHACHA20_BLOCK_NBYTES 64 21 #define CCCHACHA20_BLOCK_NBITS (CCCHACHA20_BLOCK_NBYTES * 8) 22 #define CCCHACHA20_NONCE_NBYTES 12 23 24 typedef struct { 25 uint32_t state[16]; 26 uint8_t buffer[CCCHACHA20_BLOCK_NBYTES]; 27 size_t leftover; 28 } ccchacha20_ctx; 29 30 #define CCPOLY1305_TAG_NBYTES 16 31 32 typedef struct { 33 uint32_t r0, r1, r2, r3, r4; 34 uint32_t s1, s2, s3, s4; 35 uint32_t h0, h1, h2, h3, h4; 36 uint8_t buf[16]; 37 size_t buf_used; 38 uint8_t key[16]; 39 } ccpoly1305_ctx; 40 41 42 /*! 43 @group ccchacha20poly1305 44 @abstract Encrypts and authenticates or decrypts and verifies data. 45 @discussion See RFC 7539 for details. 46 47 @warning The key-nonce pair must be unique per encryption. 48 49 @warning A single message can be at most (2^38 - 64) bytes in length. 50 51 The correct sequence of calls to encrypt is: 52 53 @code ccchacha20poly1305_init(...) 54 ccchacha20poly1305_setnonce(...) 55 ccchacha20poly1305_aad(...) (may be called zero or more times) 56 ccchacha20poly1305_encrypt(...) (may be called zero or more times) 57 ccchacha20poly1305_finalize(...) 58 59 To reuse the context for additional encryptions, follow this sequence: 60 61 @code ccchacha20poly1305_reset(...) 62 ccchacha20poly1305_setnonce(...) 63 ccchacha20poly1305_aad(...) (may be called zero or more times) 64 ccchacha20poly1305_encrypt(...) (may be called zero or more times) 65 ccchacha20poly1305_finalize(...) 66 67 To decrypt, follow this call sequence: 68 69 @code ccchacha20poly1305_init(...) 70 ccchacha20poly1305_setnonce(...) 71 ccchacha20poly1305_aad(...) (may be called zero or more times) 72 ccchacha20poly1305_decrypt(...) (may be called zero or more times) 73 ccchacha20poly1305_verify(...) (returns zero on successful decryption) 74 75 To reuse the context for additional encryptions, follow this sequence: 76 77 @code ccchacha20poly1305_reset(...) 78 ccchacha20poly1305_setnonce(...) 79 ccchacha20poly1305_aad(...) (may be called zero or more times) 80 ccchacha20poly1305_decrypt(...) (may be called zero or more times) 81 ccchacha20poly1305_verify(...) (returns zero on successful decryption) 82 */ 83 84 #define CCCHACHA20POLY1305_KEY_NBYTES (CCCHACHA20_KEY_NBYTES) 85 #define CCCHACHA20POLY1305_NONCE_NBYTES (CCCHACHA20_NONCE_NBYTES) 86 #define CCCHACHA20POLY1305_TAG_NBYTES (CCPOLY1305_TAG_NBYTES) 87 88 /* (2^32 - 1) blocks */ 89 /* (2^38 - 64) bytes */ 90 /* (2^41 - 512) bits */ 91 /* Exceeding this figure breaks confidentiality and authenticity. */ 92 #define CCCHACHA20POLY1305_TEXT_MAX_NBYTES ((1ULL << 38) - 64ULL) 93 94 #define CCCHACHA20POLY1305_STATE_SETNONCE 1 95 #define CCCHACHA20POLY1305_STATE_AAD 2 96 #define CCCHACHA20POLY1305_STATE_ENCRYPT 3 97 #define CCCHACHA20POLY1305_STATE_DECRYPT 4 98 #define CCCHACHA20POLY1305_STATE_FINAL 5 99 100 typedef struct { 101 ccchacha20_ctx chacha20_ctx; 102 ccpoly1305_ctx poly1305_ctx; 103 uint64_t aad_nbytes; 104 uint64_t text_nbytes; 105 uint8_t state; 106 } ccchacha20poly1305_ctx; 107 108 // This is just a stub right now. 109 // Eventually we will optimize by platform. 110 struct ccchacha20poly1305_info { 111 112 }; 113 114 const struct ccchacha20poly1305_info *ccchacha20poly1305_info(void); 115 116 /*! 117 @function ccchacha20poly1305_init 118 @abstract Initialize a chacha20poly1305 context. 119 120 @param info Implementation descriptor 121 @param ctx Context for this instance 122 @param key Secret chacha20 key 123 124 @result 0 iff successful. 125 126 @discussion The key is 32 bytes in length. 127 128 @warning The key-nonce pair must be unique per encryption. 129 */ 130 int ccchacha20poly1305_init(const struct ccchacha20poly1305_info *info, ccchacha20poly1305_ctx *ctx, const uint8_t *key); 131 132 /*! 133 @function ccchacha20poly1305_reset 134 @abstract Reset a chacha20poly1305 context for reuse. 135 136 @param info Implementation descriptor 137 @param ctx Context for this instance 138 139 @result 0 iff successful. 140 */ 141 int ccchacha20poly1305_reset(const struct ccchacha20poly1305_info *info, ccchacha20poly1305_ctx *ctx); 142 143 /*! 144 @function ccchacha20poly1305_setnonce 145 @abstract Set the nonce for encryption or decryption. 146 147 @param info Implementation descriptor 148 @param ctx Context for this instance 149 @param nonce Unique nonce per encryption 150 151 @result 0 iff successful. 152 153 @discussion The nonce is 12 bytes in length. 154 155 @warning The key-nonce pair must be unique per encryption. 156 */ 157 int ccchacha20poly1305_setnonce(const struct ccchacha20poly1305_info *info, ccchacha20poly1305_ctx *ctx, const uint8_t *nonce); 158 int ccchacha20poly1305_incnonce(const struct ccchacha20poly1305_info *info, ccchacha20poly1305_ctx *ctx, uint8_t *nonce); 159 160 /*! 161 @function ccchacha20poly1305_aad 162 @abstract Authenticate additional data. 163 164 @param info Descriptor for the mode 165 @param ctx Context for this instance 166 @param nbytes Length of the additional data in bytes 167 @param aad Additional data to authenticate 168 169 @result 0 iff successful. 170 171 @discussion This is typically used to authenticate data that cannot be encrypted (e.g. packet headers). 172 173 This function may be called zero or more times. 174 */ 175 int ccchacha20poly1305_aad(const struct ccchacha20poly1305_info *info, ccchacha20poly1305_ctx *ctx, size_t nbytes, const void *aad); 176 177 /*! 178 @function ccchacha20poly1305_encrypt 179 @abstract Encrypt data. 180 181 @param info Descriptor for the mode 182 @param ctx Context for this instance 183 @param nbytes Length of the plaintext in bytes 184 @param ptext Input plaintext 185 @param ctext Output ciphertext 186 187 @result 0 iff successful. 188 189 @discussion In-place processing is supported. 190 191 This function may be called zero or more times. 192 */ 193 int ccchacha20poly1305_encrypt(const struct ccchacha20poly1305_info *info, ccchacha20poly1305_ctx *ctx, size_t nbytes, const void *ptext, void *ctext); 194 195 /*! 196 @function ccchacha20poly1305_finalize 197 @abstract Finalize encryption. 198 199 @param info Descriptor for the mode 200 @param ctx Context for this instance 201 @param tag Generated authentication tag 202 203 @result 0 iff successful. 204 205 @discussion The generated tag is 16 bytes in length. 206 */ 207 int ccchacha20poly1305_finalize(const struct ccchacha20poly1305_info *info, ccchacha20poly1305_ctx *ctx, uint8_t *tag); 208 209 /*! 210 @function ccchacha20poly1305_decrypt 211 @abstract Decrypt data. 212 213 @param info Descriptor for the mode 214 @param ctx Context for this instance 215 @param nbytes Length of the ciphertext in bytes 216 @param ctext Input ciphertext 217 @param ptext Output plaintext 218 219 @result 0 iff successful. 220 221 @discussion In-place processing is supported. 222 223 This function may be called zero or more times. 224 */ 225 int ccchacha20poly1305_decrypt(const struct ccchacha20poly1305_info *info, ccchacha20poly1305_ctx *ctx, size_t nbytes, const void *ctext, void *ptext); 226 227 /*! 228 @function ccchacha20poly1305_verify 229 @abstract Verify authenticity. 230 231 @param info Descriptor for the mode 232 @param ctx Context for this instance 233 @param tag Expected authentication tag 234 235 @result 0 iff authentic and otherwise successful. 236 237 @discussion The expected tag is 16 bytes in length. 238 */ 239 int ccchacha20poly1305_verify(const struct ccchacha20poly1305_info *info, ccchacha20poly1305_ctx *ctx, const uint8_t *tag); 240 241 /*! 242 @function ccchacha20poly1305_encrypt_oneshot 243 @abstract Encrypt with chacha20poly1305. 244 245 @param info Descriptor for the mode 246 @param key Secret chacha20 key 247 @param nonce Unique nonce per encryption 248 @param aad_nbytes Length of the additional data in bytes 249 @param aad Additional data to authenticate 250 @param ptext_nbytes Length of the plaintext in bytes 251 @param ptext Input plaintext 252 @param ctext Output ciphertext 253 @param tag Generated authentication tag 254 255 @discussion See RFC 7539 for details. 256 257 The key is 32 bytes in length. 258 259 The nonce is 12 bytes in length. 260 261 The generated tag is 16 bytes in length. 262 263 In-place processing is supported. 264 265 @warning The key-nonce pair must be unique per encryption. 266 267 @warning A single message can be at most (2^38 - 64) bytes in length. 268 */ 269 int ccchacha20poly1305_encrypt_oneshot(const struct ccchacha20poly1305_info *info, const uint8_t *key, const uint8_t *nonce, size_t aad_nbytes, const void *aad, size_t ptext_nbytes, const void *ptext, void *ctext, uint8_t *tag); 270 271 /*! 272 @function ccchacha20poly1305_decrypt_oneshot 273 @abstract Decrypt with chacha20poly1305. 274 275 @param info Descriptor for the mode 276 @param key Secret chacha20 key 277 @param nonce Unique nonce per encryption 278 @param aad_nbytes Length of the additional data in bytes 279 @param aad Additional data to authenticate 280 @param ctext_nbytes Length of the ciphertext in bytes 281 @param ctext Input ciphertext 282 @param ptext Output plaintext 283 @param tag Expected authentication tag 284 285 @discussion See RFC 7539 for details. 286 287 The key is 32 bytes in length. 288 289 The nonce is 12 bytes in length. 290 291 The generated tag is 16 bytes in length. 292 293 In-place processing is supported. 294 */ 295 int ccchacha20poly1305_decrypt_oneshot(const struct ccchacha20poly1305_info *info, const uint8_t *key, const uint8_t *nonce, size_t aad_nbytes, const void *aad, size_t ctext_nbytes, const void *ctext, void *ptext, const uint8_t *tag); 296 297 #endif 298