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