1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2013-2018 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci/** Beware! 11e1051a39Sopenharmony_ci * 12e1051a39Sopenharmony_ci * Following wrapping modes were designed for AES but this implementation 13e1051a39Sopenharmony_ci * allows you to use them for any 128 bit block cipher. 14e1051a39Sopenharmony_ci */ 15e1051a39Sopenharmony_ci 16e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 17e1051a39Sopenharmony_ci#include <openssl/modes.h> 18e1051a39Sopenharmony_ci 19e1051a39Sopenharmony_ci/** RFC 3394 section 2.2.3.1 Default Initial Value */ 20e1051a39Sopenharmony_cistatic const unsigned char default_iv[] = { 21e1051a39Sopenharmony_ci 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 22e1051a39Sopenharmony_ci}; 23e1051a39Sopenharmony_ci 24e1051a39Sopenharmony_ci/** RFC 5649 section 3 Alternative Initial Value 32-bit constant */ 25e1051a39Sopenharmony_cistatic const unsigned char default_aiv[] = { 26e1051a39Sopenharmony_ci 0xA6, 0x59, 0x59, 0xA6 27e1051a39Sopenharmony_ci}; 28e1051a39Sopenharmony_ci 29e1051a39Sopenharmony_ci/** Input size limit: lower than maximum of standards but far larger than 30e1051a39Sopenharmony_ci * anything that will be used in practice. 31e1051a39Sopenharmony_ci */ 32e1051a39Sopenharmony_ci#define CRYPTO128_WRAP_MAX (1UL << 31) 33e1051a39Sopenharmony_ci 34e1051a39Sopenharmony_ci/** Wrapping according to RFC 3394 section 2.2.1. 35e1051a39Sopenharmony_ci * 36e1051a39Sopenharmony_ci * @param[in] key Key value. 37e1051a39Sopenharmony_ci * @param[in] iv IV value. Length = 8 bytes. NULL = use default_iv. 38e1051a39Sopenharmony_ci * @param[in] in Plaintext as n 64-bit blocks, n >= 2. 39e1051a39Sopenharmony_ci * @param[in] inlen Length of in. 40e1051a39Sopenharmony_ci * @param[out] out Ciphertext. Minimal buffer length = (inlen + 8) bytes. 41e1051a39Sopenharmony_ci * Input and output buffers can overlap if block function 42e1051a39Sopenharmony_ci * supports that. 43e1051a39Sopenharmony_ci * @param[in] block Block processing function. 44e1051a39Sopenharmony_ci * @return 0 if inlen does not consist of n 64-bit blocks, n >= 2. 45e1051a39Sopenharmony_ci * or if inlen > CRYPTO128_WRAP_MAX. 46e1051a39Sopenharmony_ci * Output length if wrapping succeeded. 47e1051a39Sopenharmony_ci */ 48e1051a39Sopenharmony_cisize_t CRYPTO_128_wrap(void *key, const unsigned char *iv, 49e1051a39Sopenharmony_ci unsigned char *out, 50e1051a39Sopenharmony_ci const unsigned char *in, size_t inlen, 51e1051a39Sopenharmony_ci block128_f block) 52e1051a39Sopenharmony_ci{ 53e1051a39Sopenharmony_ci unsigned char *A, B[16], *R; 54e1051a39Sopenharmony_ci size_t i, j, t; 55e1051a39Sopenharmony_ci if ((inlen & 0x7) || (inlen < 16) || (inlen > CRYPTO128_WRAP_MAX)) 56e1051a39Sopenharmony_ci return 0; 57e1051a39Sopenharmony_ci A = B; 58e1051a39Sopenharmony_ci t = 1; 59e1051a39Sopenharmony_ci memmove(out + 8, in, inlen); 60e1051a39Sopenharmony_ci if (!iv) 61e1051a39Sopenharmony_ci iv = default_iv; 62e1051a39Sopenharmony_ci 63e1051a39Sopenharmony_ci memcpy(A, iv, 8); 64e1051a39Sopenharmony_ci 65e1051a39Sopenharmony_ci for (j = 0; j < 6; j++) { 66e1051a39Sopenharmony_ci R = out + 8; 67e1051a39Sopenharmony_ci for (i = 0; i < inlen; i += 8, t++, R += 8) { 68e1051a39Sopenharmony_ci memcpy(B + 8, R, 8); 69e1051a39Sopenharmony_ci block(B, B, key); 70e1051a39Sopenharmony_ci A[7] ^= (unsigned char)(t & 0xff); 71e1051a39Sopenharmony_ci if (t > 0xff) { 72e1051a39Sopenharmony_ci A[6] ^= (unsigned char)((t >> 8) & 0xff); 73e1051a39Sopenharmony_ci A[5] ^= (unsigned char)((t >> 16) & 0xff); 74e1051a39Sopenharmony_ci A[4] ^= (unsigned char)((t >> 24) & 0xff); 75e1051a39Sopenharmony_ci } 76e1051a39Sopenharmony_ci memcpy(R, B + 8, 8); 77e1051a39Sopenharmony_ci } 78e1051a39Sopenharmony_ci } 79e1051a39Sopenharmony_ci memcpy(out, A, 8); 80e1051a39Sopenharmony_ci return inlen + 8; 81e1051a39Sopenharmony_ci} 82e1051a39Sopenharmony_ci 83e1051a39Sopenharmony_ci/** Unwrapping according to RFC 3394 section 2.2.2 steps 1-2. 84e1051a39Sopenharmony_ci * The IV check (step 3) is responsibility of the caller. 85e1051a39Sopenharmony_ci * 86e1051a39Sopenharmony_ci * @param[in] key Key value. 87e1051a39Sopenharmony_ci * @param[out] iv Unchecked IV value. Minimal buffer length = 8 bytes. 88e1051a39Sopenharmony_ci * @param[out] out Plaintext without IV. 89e1051a39Sopenharmony_ci * Minimal buffer length = (inlen - 8) bytes. 90e1051a39Sopenharmony_ci * Input and output buffers can overlap if block function 91e1051a39Sopenharmony_ci * supports that. 92e1051a39Sopenharmony_ci * @param[in] in Ciphertext as n 64-bit blocks. 93e1051a39Sopenharmony_ci * @param[in] inlen Length of in. 94e1051a39Sopenharmony_ci * @param[in] block Block processing function. 95e1051a39Sopenharmony_ci * @return 0 if inlen is out of range [24, CRYPTO128_WRAP_MAX] 96e1051a39Sopenharmony_ci * or if inlen is not a multiple of 8. 97e1051a39Sopenharmony_ci * Output length otherwise. 98e1051a39Sopenharmony_ci */ 99e1051a39Sopenharmony_cistatic size_t crypto_128_unwrap_raw(void *key, unsigned char *iv, 100e1051a39Sopenharmony_ci unsigned char *out, 101e1051a39Sopenharmony_ci const unsigned char *in, size_t inlen, 102e1051a39Sopenharmony_ci block128_f block) 103e1051a39Sopenharmony_ci{ 104e1051a39Sopenharmony_ci unsigned char *A, B[16], *R; 105e1051a39Sopenharmony_ci size_t i, j, t; 106e1051a39Sopenharmony_ci inlen -= 8; 107e1051a39Sopenharmony_ci if ((inlen & 0x7) || (inlen < 16) || (inlen > CRYPTO128_WRAP_MAX)) 108e1051a39Sopenharmony_ci return 0; 109e1051a39Sopenharmony_ci A = B; 110e1051a39Sopenharmony_ci t = 6 * (inlen >> 3); 111e1051a39Sopenharmony_ci memcpy(A, in, 8); 112e1051a39Sopenharmony_ci memmove(out, in + 8, inlen); 113e1051a39Sopenharmony_ci for (j = 0; j < 6; j++) { 114e1051a39Sopenharmony_ci R = out + inlen - 8; 115e1051a39Sopenharmony_ci for (i = 0; i < inlen; i += 8, t--, R -= 8) { 116e1051a39Sopenharmony_ci A[7] ^= (unsigned char)(t & 0xff); 117e1051a39Sopenharmony_ci if (t > 0xff) { 118e1051a39Sopenharmony_ci A[6] ^= (unsigned char)((t >> 8) & 0xff); 119e1051a39Sopenharmony_ci A[5] ^= (unsigned char)((t >> 16) & 0xff); 120e1051a39Sopenharmony_ci A[4] ^= (unsigned char)((t >> 24) & 0xff); 121e1051a39Sopenharmony_ci } 122e1051a39Sopenharmony_ci memcpy(B + 8, R, 8); 123e1051a39Sopenharmony_ci block(B, B, key); 124e1051a39Sopenharmony_ci memcpy(R, B + 8, 8); 125e1051a39Sopenharmony_ci } 126e1051a39Sopenharmony_ci } 127e1051a39Sopenharmony_ci memcpy(iv, A, 8); 128e1051a39Sopenharmony_ci return inlen; 129e1051a39Sopenharmony_ci} 130e1051a39Sopenharmony_ci 131e1051a39Sopenharmony_ci/** Unwrapping according to RFC 3394 section 2.2.2, including the IV check. 132e1051a39Sopenharmony_ci * The first block of plaintext has to match the supplied IV, otherwise an 133e1051a39Sopenharmony_ci * error is returned. 134e1051a39Sopenharmony_ci * 135e1051a39Sopenharmony_ci * @param[in] key Key value. 136e1051a39Sopenharmony_ci * @param[out] iv IV value to match against. Length = 8 bytes. 137e1051a39Sopenharmony_ci * NULL = use default_iv. 138e1051a39Sopenharmony_ci * @param[out] out Plaintext without IV. 139e1051a39Sopenharmony_ci * Minimal buffer length = (inlen - 8) bytes. 140e1051a39Sopenharmony_ci * Input and output buffers can overlap if block function 141e1051a39Sopenharmony_ci * supports that. 142e1051a39Sopenharmony_ci * @param[in] in Ciphertext as n 64-bit blocks. 143e1051a39Sopenharmony_ci * @param[in] inlen Length of in. 144e1051a39Sopenharmony_ci * @param[in] block Block processing function. 145e1051a39Sopenharmony_ci * @return 0 if inlen is out of range [24, CRYPTO128_WRAP_MAX] 146e1051a39Sopenharmony_ci * or if inlen is not a multiple of 8 147e1051a39Sopenharmony_ci * or if IV doesn't match expected value. 148e1051a39Sopenharmony_ci * Output length otherwise. 149e1051a39Sopenharmony_ci */ 150e1051a39Sopenharmony_cisize_t CRYPTO_128_unwrap(void *key, const unsigned char *iv, 151e1051a39Sopenharmony_ci unsigned char *out, const unsigned char *in, 152e1051a39Sopenharmony_ci size_t inlen, block128_f block) 153e1051a39Sopenharmony_ci{ 154e1051a39Sopenharmony_ci size_t ret; 155e1051a39Sopenharmony_ci unsigned char got_iv[8]; 156e1051a39Sopenharmony_ci 157e1051a39Sopenharmony_ci ret = crypto_128_unwrap_raw(key, got_iv, out, in, inlen, block); 158e1051a39Sopenharmony_ci if (ret == 0) 159e1051a39Sopenharmony_ci return 0; 160e1051a39Sopenharmony_ci 161e1051a39Sopenharmony_ci if (!iv) 162e1051a39Sopenharmony_ci iv = default_iv; 163e1051a39Sopenharmony_ci if (CRYPTO_memcmp(got_iv, iv, 8)) { 164e1051a39Sopenharmony_ci OPENSSL_cleanse(out, ret); 165e1051a39Sopenharmony_ci return 0; 166e1051a39Sopenharmony_ci } 167e1051a39Sopenharmony_ci return ret; 168e1051a39Sopenharmony_ci} 169e1051a39Sopenharmony_ci 170e1051a39Sopenharmony_ci/** Wrapping according to RFC 5649 section 4.1. 171e1051a39Sopenharmony_ci * 172e1051a39Sopenharmony_ci * @param[in] key Key value. 173e1051a39Sopenharmony_ci * @param[in] icv (Non-standard) IV, 4 bytes. NULL = use default_aiv. 174e1051a39Sopenharmony_ci * @param[out] out Ciphertext. Minimal buffer length = (inlen + 15) bytes. 175e1051a39Sopenharmony_ci * Input and output buffers can overlap if block function 176e1051a39Sopenharmony_ci * supports that. 177e1051a39Sopenharmony_ci * @param[in] in Plaintext as n 64-bit blocks, n >= 2. 178e1051a39Sopenharmony_ci * @param[in] inlen Length of in. 179e1051a39Sopenharmony_ci * @param[in] block Block processing function. 180e1051a39Sopenharmony_ci * @return 0 if inlen is out of range [1, CRYPTO128_WRAP_MAX]. 181e1051a39Sopenharmony_ci * Output length if wrapping succeeded. 182e1051a39Sopenharmony_ci */ 183e1051a39Sopenharmony_cisize_t CRYPTO_128_wrap_pad(void *key, const unsigned char *icv, 184e1051a39Sopenharmony_ci unsigned char *out, 185e1051a39Sopenharmony_ci const unsigned char *in, size_t inlen, 186e1051a39Sopenharmony_ci block128_f block) 187e1051a39Sopenharmony_ci{ 188e1051a39Sopenharmony_ci /* n: number of 64-bit blocks in the padded key data 189e1051a39Sopenharmony_ci * 190e1051a39Sopenharmony_ci * If length of plain text is not a multiple of 8, pad the plain text octet 191e1051a39Sopenharmony_ci * string on the right with octets of zeros, where final length is the 192e1051a39Sopenharmony_ci * smallest multiple of 8 that is greater than length of plain text. 193e1051a39Sopenharmony_ci * If length of plain text is a multiple of 8, then there is no padding. */ 194e1051a39Sopenharmony_ci const size_t blocks_padded = (inlen + 7) / 8; /* CEILING(m/8) */ 195e1051a39Sopenharmony_ci const size_t padded_len = blocks_padded * 8; 196e1051a39Sopenharmony_ci const size_t padding_len = padded_len - inlen; 197e1051a39Sopenharmony_ci /* RFC 5649 section 3: Alternative Initial Value */ 198e1051a39Sopenharmony_ci unsigned char aiv[8]; 199e1051a39Sopenharmony_ci int ret; 200e1051a39Sopenharmony_ci 201e1051a39Sopenharmony_ci /* Section 1: use 32-bit fixed field for plaintext octet length */ 202e1051a39Sopenharmony_ci if (inlen == 0 || inlen >= CRYPTO128_WRAP_MAX) 203e1051a39Sopenharmony_ci return 0; 204e1051a39Sopenharmony_ci 205e1051a39Sopenharmony_ci /* Section 3: Alternative Initial Value */ 206e1051a39Sopenharmony_ci if (!icv) 207e1051a39Sopenharmony_ci memcpy(aiv, default_aiv, 4); 208e1051a39Sopenharmony_ci else 209e1051a39Sopenharmony_ci memcpy(aiv, icv, 4); /* Standard doesn't mention this. */ 210e1051a39Sopenharmony_ci 211e1051a39Sopenharmony_ci aiv[4] = (inlen >> 24) & 0xFF; 212e1051a39Sopenharmony_ci aiv[5] = (inlen >> 16) & 0xFF; 213e1051a39Sopenharmony_ci aiv[6] = (inlen >> 8) & 0xFF; 214e1051a39Sopenharmony_ci aiv[7] = inlen & 0xFF; 215e1051a39Sopenharmony_ci 216e1051a39Sopenharmony_ci if (padded_len == 8) { 217e1051a39Sopenharmony_ci /* 218e1051a39Sopenharmony_ci * Section 4.1 - special case in step 2: If the padded plaintext 219e1051a39Sopenharmony_ci * contains exactly eight octets, then prepend the AIV and encrypt 220e1051a39Sopenharmony_ci * the resulting 128-bit block using AES in ECB mode. 221e1051a39Sopenharmony_ci */ 222e1051a39Sopenharmony_ci memmove(out + 8, in, inlen); 223e1051a39Sopenharmony_ci memcpy(out, aiv, 8); 224e1051a39Sopenharmony_ci memset(out + 8 + inlen, 0, padding_len); 225e1051a39Sopenharmony_ci block(out, out, key); 226e1051a39Sopenharmony_ci ret = 16; /* AIV + padded input */ 227e1051a39Sopenharmony_ci } else { 228e1051a39Sopenharmony_ci memmove(out, in, inlen); 229e1051a39Sopenharmony_ci memset(out + inlen, 0, padding_len); /* Section 4.1 step 1 */ 230e1051a39Sopenharmony_ci ret = CRYPTO_128_wrap(key, aiv, out, out, padded_len, block); 231e1051a39Sopenharmony_ci } 232e1051a39Sopenharmony_ci 233e1051a39Sopenharmony_ci return ret; 234e1051a39Sopenharmony_ci} 235e1051a39Sopenharmony_ci 236e1051a39Sopenharmony_ci/** Unwrapping according to RFC 5649 section 4.2. 237e1051a39Sopenharmony_ci * 238e1051a39Sopenharmony_ci * @param[in] key Key value. 239e1051a39Sopenharmony_ci * @param[in] icv (Non-standard) IV, 4 bytes. NULL = use default_aiv. 240e1051a39Sopenharmony_ci * @param[out] out Plaintext. Minimal buffer length = (inlen - 8) bytes. 241e1051a39Sopenharmony_ci * Input and output buffers can overlap if block function 242e1051a39Sopenharmony_ci * supports that. 243e1051a39Sopenharmony_ci * @param[in] in Ciphertext as n 64-bit blocks. 244e1051a39Sopenharmony_ci * @param[in] inlen Length of in. 245e1051a39Sopenharmony_ci * @param[in] block Block processing function. 246e1051a39Sopenharmony_ci * @return 0 if inlen is out of range [16, CRYPTO128_WRAP_MAX], 247e1051a39Sopenharmony_ci * or if inlen is not a multiple of 8 248e1051a39Sopenharmony_ci * or if IV and message length indicator doesn't match. 249e1051a39Sopenharmony_ci * Output length if unwrapping succeeded and IV matches. 250e1051a39Sopenharmony_ci */ 251e1051a39Sopenharmony_cisize_t CRYPTO_128_unwrap_pad(void *key, const unsigned char *icv, 252e1051a39Sopenharmony_ci unsigned char *out, 253e1051a39Sopenharmony_ci const unsigned char *in, size_t inlen, 254e1051a39Sopenharmony_ci block128_f block) 255e1051a39Sopenharmony_ci{ 256e1051a39Sopenharmony_ci /* n: number of 64-bit blocks in the padded key data */ 257e1051a39Sopenharmony_ci size_t n = inlen / 8 - 1; 258e1051a39Sopenharmony_ci size_t padded_len; 259e1051a39Sopenharmony_ci size_t padding_len; 260e1051a39Sopenharmony_ci size_t ptext_len; 261e1051a39Sopenharmony_ci /* RFC 5649 section 3: Alternative Initial Value */ 262e1051a39Sopenharmony_ci unsigned char aiv[8]; 263e1051a39Sopenharmony_ci static unsigned char zeros[8] = { 0x0 }; 264e1051a39Sopenharmony_ci size_t ret; 265e1051a39Sopenharmony_ci 266e1051a39Sopenharmony_ci /* Section 4.2: Ciphertext length has to be (n+1) 64-bit blocks. */ 267e1051a39Sopenharmony_ci if ((inlen & 0x7) != 0 || inlen < 16 || inlen >= CRYPTO128_WRAP_MAX) 268e1051a39Sopenharmony_ci return 0; 269e1051a39Sopenharmony_ci 270e1051a39Sopenharmony_ci if (inlen == 16) { 271e1051a39Sopenharmony_ci /* 272e1051a39Sopenharmony_ci * Section 4.2 - special case in step 1: When n=1, the ciphertext 273e1051a39Sopenharmony_ci * contains exactly two 64-bit blocks and they are decrypted as a 274e1051a39Sopenharmony_ci * single AES block using AES in ECB mode: AIV | P[1] = DEC(K, C[0] | 275e1051a39Sopenharmony_ci * C[1]) 276e1051a39Sopenharmony_ci */ 277e1051a39Sopenharmony_ci unsigned char buff[16]; 278e1051a39Sopenharmony_ci 279e1051a39Sopenharmony_ci block(in, buff, key); 280e1051a39Sopenharmony_ci memcpy(aiv, buff, 8); 281e1051a39Sopenharmony_ci /* Remove AIV */ 282e1051a39Sopenharmony_ci memcpy(out, buff + 8, 8); 283e1051a39Sopenharmony_ci padded_len = 8; 284e1051a39Sopenharmony_ci OPENSSL_cleanse(buff, inlen); 285e1051a39Sopenharmony_ci } else { 286e1051a39Sopenharmony_ci padded_len = inlen - 8; 287e1051a39Sopenharmony_ci ret = crypto_128_unwrap_raw(key, aiv, out, in, inlen, block); 288e1051a39Sopenharmony_ci if (padded_len != ret) { 289e1051a39Sopenharmony_ci OPENSSL_cleanse(out, inlen); 290e1051a39Sopenharmony_ci return 0; 291e1051a39Sopenharmony_ci } 292e1051a39Sopenharmony_ci } 293e1051a39Sopenharmony_ci 294e1051a39Sopenharmony_ci /* 295e1051a39Sopenharmony_ci * Section 3: AIV checks: Check that MSB(32,A) = A65959A6. Optionally a 296e1051a39Sopenharmony_ci * user-supplied value can be used (even if standard doesn't mention 297e1051a39Sopenharmony_ci * this). 298e1051a39Sopenharmony_ci */ 299e1051a39Sopenharmony_ci if ((!icv && CRYPTO_memcmp(aiv, default_aiv, 4)) 300e1051a39Sopenharmony_ci || (icv && CRYPTO_memcmp(aiv, icv, 4))) { 301e1051a39Sopenharmony_ci OPENSSL_cleanse(out, inlen); 302e1051a39Sopenharmony_ci return 0; 303e1051a39Sopenharmony_ci } 304e1051a39Sopenharmony_ci 305e1051a39Sopenharmony_ci /* 306e1051a39Sopenharmony_ci * Check that 8*(n-1) < LSB(32,AIV) <= 8*n. If so, let ptext_len = 307e1051a39Sopenharmony_ci * LSB(32,AIV). 308e1051a39Sopenharmony_ci */ 309e1051a39Sopenharmony_ci 310e1051a39Sopenharmony_ci ptext_len = ((unsigned int)aiv[4] << 24) 311e1051a39Sopenharmony_ci | ((unsigned int)aiv[5] << 16) 312e1051a39Sopenharmony_ci | ((unsigned int)aiv[6] << 8) 313e1051a39Sopenharmony_ci | (unsigned int)aiv[7]; 314e1051a39Sopenharmony_ci if (8 * (n - 1) >= ptext_len || ptext_len > 8 * n) { 315e1051a39Sopenharmony_ci OPENSSL_cleanse(out, inlen); 316e1051a39Sopenharmony_ci return 0; 317e1051a39Sopenharmony_ci } 318e1051a39Sopenharmony_ci 319e1051a39Sopenharmony_ci /* 320e1051a39Sopenharmony_ci * Check that the rightmost padding_len octets of the output data are 321e1051a39Sopenharmony_ci * zero. 322e1051a39Sopenharmony_ci */ 323e1051a39Sopenharmony_ci padding_len = padded_len - ptext_len; 324e1051a39Sopenharmony_ci if (CRYPTO_memcmp(out + ptext_len, zeros, padding_len) != 0) { 325e1051a39Sopenharmony_ci OPENSSL_cleanse(out, inlen); 326e1051a39Sopenharmony_ci return 0; 327e1051a39Sopenharmony_ci } 328e1051a39Sopenharmony_ci 329e1051a39Sopenharmony_ci /* Section 4.2 step 3: Remove padding */ 330e1051a39Sopenharmony_ci return ptext_len; 331e1051a39Sopenharmony_ci} 332