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