/src/nettle-with-libgmp/nist-keywrap.c
Line | Count | Source |
1 | | /* nist-keywrap.c |
2 | | |
3 | | AES Key Wrap function. |
4 | | implements RFC 3394 |
5 | | https://tools.ietf.org/html/rfc3394 |
6 | | |
7 | | Copyright (C) 2021 Nicolas Mora |
8 | | 2021 Niels Möller |
9 | | |
10 | | This file is part of GNU Nettle. |
11 | | |
12 | | GNU Nettle is free software: you can redistribute it and/or |
13 | | modify it under the terms of either: |
14 | | |
15 | | * the GNU Lesser General Public License as published by the Free |
16 | | Software Foundation; either version 3 of the License, or (at your |
17 | | option) any later version. |
18 | | |
19 | | or |
20 | | |
21 | | * the GNU General Public License as published by the Free |
22 | | Software Foundation; either version 2 of the License, or (at your |
23 | | option) any later version. |
24 | | |
25 | | or both in parallel, as here. |
26 | | |
27 | | GNU Nettle is distributed in the hope that it will be useful, |
28 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
29 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
30 | | General Public License for more details. |
31 | | |
32 | | You should have received copies of the GNU General Public License and |
33 | | the GNU Lesser General Public License along with this program. If |
34 | | not, see http://www.gnu.org/licenses/. |
35 | | */ |
36 | | |
37 | | #if HAVE_CONFIG_H |
38 | | #include "config.h" |
39 | | #endif |
40 | | |
41 | | #include <assert.h> |
42 | | #include <string.h> |
43 | | |
44 | | #include "nist-keywrap.h" |
45 | | #include "memops.h" |
46 | | #include "macros.h" |
47 | | #include "bswap-internal.h" |
48 | | |
49 | | void |
50 | | nist_keywrap16 (const void *ctx, nettle_cipher_func *encrypt, |
51 | | const uint8_t *iv, size_t ciphertext_length, |
52 | | uint8_t *ciphertext, const uint8_t *cleartext) |
53 | 234 | { |
54 | 234 | union nettle_block16 I, B; |
55 | 234 | union nettle_block8 A; |
56 | 234 | size_t i, j, n; |
57 | 234 | uint8_t *R = ciphertext + 8; |
58 | | |
59 | | /* ciphertext_length must be at least 16 |
60 | | * and be divisible by 8 */ |
61 | 234 | assert (ciphertext_length >= 16); |
62 | 234 | assert (!(ciphertext_length % 8)); |
63 | | |
64 | 234 | n = (ciphertext_length - 8) / 8; |
65 | 234 | memcpy (R, cleartext, (ciphertext_length - 8)); |
66 | 234 | memcpy (A.b, iv, 8); |
67 | | |
68 | 1.63k | for (j = 0; j < 6; j++) |
69 | 1.40k | { |
70 | 4.21k | for (i = 0; i < n; i++) |
71 | 2.80k | { |
72 | | /* I = A | R[1] */ |
73 | 2.80k | I.u64[0] = A.u64; |
74 | 2.80k | memcpy (I.b + 8, R + (i * 8), 8); |
75 | | |
76 | | /* B = AES(K, I) */ |
77 | 2.80k | encrypt (ctx, 16, B.b, I.b); |
78 | | |
79 | | /* A = MSB(64, B) ^ t where t = (n*j)+i */ |
80 | 2.80k | A.u64 = B.u64[0] ^ bswap64_if_le ((n * j) + (i + 1)); |
81 | | |
82 | | /* R[i] = LSB(64, B) */ |
83 | 2.80k | memcpy (R + (i * 8), B.b + 8, 8); |
84 | 2.80k | } |
85 | 1.40k | } |
86 | | |
87 | 234 | memcpy (ciphertext, A.b, 8); |
88 | 234 | } |
89 | | |
90 | | int |
91 | | nist_keyunwrap16 (const void *ctx, nettle_cipher_func *decrypt, |
92 | | const uint8_t *iv, size_t cleartext_length, |
93 | | uint8_t *cleartext, const uint8_t *ciphertext) |
94 | 280 | { |
95 | 280 | union nettle_block16 I, B; |
96 | 280 | union nettle_block8 A; |
97 | 280 | int i, j; |
98 | 280 | size_t n; |
99 | 280 | uint8_t *R = cleartext; |
100 | | |
101 | | /* cleartext_length must be at least 8 |
102 | | * and be divisible by 8 */ |
103 | 280 | assert (cleartext_length >= 8); |
104 | 280 | assert (!(cleartext_length % 8)); |
105 | | |
106 | 280 | n = (cleartext_length / 8); |
107 | 280 | memcpy (A.b, ciphertext, 8); |
108 | 280 | memcpy (R, ciphertext + 8, cleartext_length); |
109 | | |
110 | 1.96k | for (j = 5; j >= 0; j--) |
111 | 1.68k | { |
112 | 4.76k | for (i = n - 1; i >= 0; i--) |
113 | 3.08k | { |
114 | | /* B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i */ |
115 | 3.08k | I.u64[0] = A.u64 ^ bswap64_if_le ((n * j) + (i + 1)); |
116 | 3.08k | memcpy (I.b + 8, R + (i * 8), 8); |
117 | 3.08k | decrypt (ctx, 16, B.b, I.b); |
118 | | |
119 | | /* A = MSB(64, B) */ |
120 | 3.08k | A.u64 = B.u64[0]; |
121 | | |
122 | | /* R[i] = LSB(64, B) */ |
123 | 3.08k | memcpy (R + (i * 8), B.b + 8, 8); |
124 | 3.08k | } |
125 | 1.68k | } |
126 | | |
127 | 280 | return memeql_sec (A.b, iv, 8); |
128 | 280 | } |
129 | | |
130 | | void |
131 | | aes128_keywrap (struct aes128_ctx *ctx, |
132 | | const uint8_t *iv, size_t ciphertext_length, |
133 | | uint8_t *ciphertext, const uint8_t *cleartext) |
134 | 70 | { |
135 | 70 | nist_keywrap16 (ctx, (nettle_cipher_func *) & aes128_encrypt, |
136 | 70 | iv, ciphertext_length, ciphertext, cleartext); |
137 | 70 | } |
138 | | |
139 | | void |
140 | | aes192_keywrap (struct aes192_ctx *ctx, |
141 | | const uint8_t *iv, size_t ciphertext_length, |
142 | | uint8_t *ciphertext, const uint8_t *cleartext) |
143 | 101 | { |
144 | 101 | nist_keywrap16 (ctx, (nettle_cipher_func *) & aes192_encrypt, |
145 | 101 | iv, ciphertext_length, ciphertext, cleartext); |
146 | 101 | } |
147 | | |
148 | | void |
149 | | aes256_keywrap (struct aes256_ctx *ctx, |
150 | | const uint8_t *iv, size_t ciphertext_length, |
151 | | uint8_t *ciphertext, const uint8_t *cleartext) |
152 | 63 | { |
153 | 63 | nist_keywrap16 (ctx, (nettle_cipher_func *) & aes256_encrypt, |
154 | 63 | iv, ciphertext_length, ciphertext, cleartext); |
155 | 63 | } |
156 | | |
157 | | int |
158 | | aes128_keyunwrap (struct aes128_ctx *ctx, |
159 | | const uint8_t *iv, size_t cleartext_length, |
160 | | uint8_t *cleartext, const uint8_t *ciphertext) |
161 | 90 | { |
162 | 90 | return nist_keyunwrap16 (ctx, (nettle_cipher_func *) & aes128_decrypt, |
163 | 90 | iv, cleartext_length, cleartext, ciphertext); |
164 | 90 | } |
165 | | |
166 | | int |
167 | | aes192_keyunwrap (struct aes192_ctx *ctx, |
168 | | const uint8_t *iv, size_t cleartext_length, |
169 | | uint8_t *cleartext, const uint8_t *ciphertext) |
170 | 105 | { |
171 | 105 | return nist_keyunwrap16 (ctx, (nettle_cipher_func *) & aes192_decrypt, |
172 | 105 | iv, cleartext_length, cleartext, ciphertext); |
173 | 105 | } |
174 | | |
175 | | int |
176 | | aes256_keyunwrap (struct aes256_ctx *ctx, |
177 | | const uint8_t *iv, size_t cleartext_length, |
178 | | uint8_t *cleartext, const uint8_t *ciphertext) |
179 | 85 | { |
180 | 85 | return nist_keyunwrap16 (ctx, (nettle_cipher_func *) & aes256_decrypt, |
181 | 85 | iv, cleartext_length, cleartext, ciphertext); |
182 | 85 | } |