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