diff options
author | jsing <> | 2014-05-15 15:13:56 +0000 |
---|---|---|
committer | jsing <> | 2014-05-15 15:13:56 +0000 |
commit | 58717fb038a81b7b57c09bf92e8a67e2c23377e2 (patch) | |
tree | 4faa38278c62b9bbe0e7ded53414d5ae7564efa1 | |
parent | fec12ac838b5428d9c1c0d074de2cfcfc2d60f6a (diff) | |
download | openbsd-58717fb038a81b7b57c09bf92e8a67e2c23377e2.tar.gz openbsd-58717fb038a81b7b57c09bf92e8a67e2c23377e2.tar.bz2 openbsd-58717fb038a81b7b57c09bf92e8a67e2c23377e2.zip |
KNF.
-rw-r--r-- | src/lib/libcrypto/evp/e_chacha20poly1305.c | 137 | ||||
-rw-r--r-- | src/lib/libssl/src/crypto/evp/e_chacha20poly1305.c | 137 |
2 files changed, 134 insertions, 140 deletions
diff --git a/src/lib/libcrypto/evp/e_chacha20poly1305.c b/src/lib/libcrypto/evp/e_chacha20poly1305.c index 9df6b7c453..6e4a3f507a 100644 --- a/src/lib/libcrypto/evp/e_chacha20poly1305.c +++ b/src/lib/libcrypto/evp/e_chacha20poly1305.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * are met: | 6 | * are met: |
7 | * | 7 | * |
8 | * 1. Redistributions of source code must retain the above copyright | 8 | * 1. Redistributions of source code must retain the above copyright |
9 | * notice, this list of conditions and the following disclaimer. | 9 | * notice, this list of conditions and the following disclaimer. |
10 | * | 10 | * |
11 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
12 | * notice, this list of conditions and the following disclaimer in | 12 | * notice, this list of conditions and the following disclaimer in |
@@ -63,24 +63,24 @@ | |||
63 | #define POLY1305_TAG_LEN 16 | 63 | #define POLY1305_TAG_LEN 16 |
64 | #define CHACHA20_NONCE_LEN 8 | 64 | #define CHACHA20_NONCE_LEN 8 |
65 | 65 | ||
66 | struct aead_chacha20_poly1305_ctx | 66 | struct aead_chacha20_poly1305_ctx { |
67 | { | ||
68 | unsigned char key[32]; | 67 | unsigned char key[32]; |
69 | unsigned char tag_len; | 68 | unsigned char tag_len; |
70 | }; | 69 | }; |
71 | 70 | ||
72 | static int aead_chacha20_poly1305_init(EVP_AEAD_CTX *ctx, const unsigned char *key, size_t key_len, size_t tag_len) | 71 | static int |
73 | { | 72 | aead_chacha20_poly1305_init(EVP_AEAD_CTX *ctx, const unsigned char *key, |
73 | size_t key_len, size_t tag_len) | ||
74 | { | ||
74 | struct aead_chacha20_poly1305_ctx *c20_ctx; | 75 | struct aead_chacha20_poly1305_ctx *c20_ctx; |
75 | 76 | ||
76 | if (tag_len == 0) | 77 | if (tag_len == 0) |
77 | tag_len = POLY1305_TAG_LEN; | 78 | tag_len = POLY1305_TAG_LEN; |
78 | 79 | ||
79 | if (tag_len > POLY1305_TAG_LEN) | 80 | if (tag_len > POLY1305_TAG_LEN) { |
80 | { | ||
81 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_INIT, EVP_R_TOO_LARGE); | 81 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_INIT, EVP_R_TOO_LARGE); |
82 | return 0; | 82 | return 0; |
83 | } | 83 | } |
84 | 84 | ||
85 | if (key_len != sizeof(c20_ctx->key)) | 85 | if (key_len != sizeof(c20_ctx->key)) |
86 | return 0; /* internal error - EVP_AEAD_CTX_init should catch this. */ | 86 | return 0; /* internal error - EVP_AEAD_CTX_init should catch this. */ |
@@ -94,38 +94,39 @@ static int aead_chacha20_poly1305_init(EVP_AEAD_CTX *ctx, const unsigned char *k | |||
94 | ctx->aead_state = c20_ctx; | 94 | ctx->aead_state = c20_ctx; |
95 | 95 | ||
96 | return 1; | 96 | return 1; |
97 | } | 97 | } |
98 | 98 | ||
99 | static void aead_chacha20_poly1305_cleanup(EVP_AEAD_CTX *ctx) | 99 | static void |
100 | { | 100 | aead_chacha20_poly1305_cleanup(EVP_AEAD_CTX *ctx) |
101 | { | ||
101 | struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; | 102 | struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; |
102 | OPENSSL_cleanse(c20_ctx->key, sizeof(c20_ctx->key)); | 103 | OPENSSL_cleanse(c20_ctx->key, sizeof(c20_ctx->key)); |
103 | OPENSSL_free(c20_ctx); | 104 | OPENSSL_free(c20_ctx); |
104 | } | 105 | } |
105 | 106 | ||
106 | static void poly1305_update_with_length(poly1305_state *poly1305, | 107 | static void |
107 | const unsigned char *data, size_t data_len) | 108 | poly1305_update_with_length(poly1305_state *poly1305, |
108 | { | 109 | const unsigned char *data, size_t data_len) |
110 | { | ||
109 | size_t j = data_len; | 111 | size_t j = data_len; |
110 | unsigned char length_bytes[8]; | 112 | unsigned char length_bytes[8]; |
111 | unsigned i; | 113 | unsigned i; |
112 | 114 | ||
113 | for (i = 0; i < sizeof(length_bytes); i++) | 115 | for (i = 0; i < sizeof(length_bytes); i++) { |
114 | { | ||
115 | length_bytes[i] = j; | 116 | length_bytes[i] = j; |
116 | j >>= 8; | 117 | j >>= 8; |
117 | } | 118 | } |
118 | 119 | ||
119 | CRYPTO_poly1305_update(poly1305, data, data_len); | 120 | CRYPTO_poly1305_update(poly1305, data, data_len); |
120 | CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes)); | 121 | CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes)); |
121 | } | 122 | } |
122 | 123 | ||
123 | static ssize_t aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, | 124 | static ssize_t |
124 | unsigned char *out, size_t max_out_len, | 125 | aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, |
125 | const unsigned char *nonce, size_t nonce_len, | 126 | size_t max_out_len, const unsigned char *nonce, size_t nonce_len, |
126 | const unsigned char *in, size_t in_len, | 127 | const unsigned char *in, size_t in_len, const unsigned char *ad, |
127 | const unsigned char *ad, size_t ad_len) | 128 | size_t ad_len) |
128 | { | 129 | { |
129 | const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; | 130 | const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; |
130 | unsigned char poly1305_key[32]; | 131 | unsigned char poly1305_key[32]; |
131 | poly1305_state poly1305; | 132 | poly1305_state poly1305; |
@@ -138,50 +139,48 @@ static ssize_t aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, | |||
138 | * 32-bits and this produces a warning because it's always false. | 139 | * 32-bits and this produces a warning because it's always false. |
139 | * Casting to uint64_t inside the conditional is not sufficient to stop | 140 | * Casting to uint64_t inside the conditional is not sufficient to stop |
140 | * the warning. */ | 141 | * the warning. */ |
141 | if (in_len_64 >= (1ull << 32)*64-64) | 142 | if (in_len_64 >= (1ull << 32)*64 - 64) { |
142 | { | ||
143 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, EVP_R_TOO_LARGE); | 143 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, EVP_R_TOO_LARGE); |
144 | return -1; | 144 | return -1; |
145 | } | 145 | } |
146 | 146 | ||
147 | if (max_out_len < in_len + c20_ctx->tag_len) | 147 | if (max_out_len < in_len + c20_ctx->tag_len) { |
148 | { | 148 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, |
149 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, EVP_R_BUFFER_TOO_SMALL); | 149 | EVP_R_BUFFER_TOO_SMALL); |
150 | return -1; | 150 | return -1; |
151 | } | 151 | } |
152 | 152 | ||
153 | if (nonce_len != CHACHA20_NONCE_LEN) | 153 | if (nonce_len != CHACHA20_NONCE_LEN) { |
154 | { | ||
155 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, EVP_R_IV_TOO_LARGE); | 154 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, EVP_R_IV_TOO_LARGE); |
156 | return -1; | 155 | return -1; |
157 | } | 156 | } |
158 | 157 | ||
159 | memset(poly1305_key, 0, sizeof(poly1305_key)); | 158 | memset(poly1305_key, 0, sizeof(poly1305_key)); |
160 | CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), c20_ctx->key, nonce, 0); | 159 | CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), |
160 | c20_ctx->key, nonce, 0); | ||
161 | 161 | ||
162 | CRYPTO_poly1305_init(&poly1305, poly1305_key); | 162 | CRYPTO_poly1305_init(&poly1305, poly1305_key); |
163 | poly1305_update_with_length(&poly1305, ad, ad_len); | 163 | poly1305_update_with_length(&poly1305, ad, ad_len); |
164 | CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1); | 164 | CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1); |
165 | poly1305_update_with_length(&poly1305, out, in_len); | 165 | poly1305_update_with_length(&poly1305, out, in_len); |
166 | 166 | ||
167 | if (c20_ctx->tag_len != POLY1305_TAG_LEN) | 167 | if (c20_ctx->tag_len != POLY1305_TAG_LEN) { |
168 | { | ||
169 | unsigned char tag[POLY1305_TAG_LEN]; | 168 | unsigned char tag[POLY1305_TAG_LEN]; |
170 | CRYPTO_poly1305_finish(&poly1305, tag); | 169 | CRYPTO_poly1305_finish(&poly1305, tag); |
171 | memcpy(out + in_len, tag, c20_ctx->tag_len); | 170 | memcpy(out + in_len, tag, c20_ctx->tag_len); |
172 | return in_len + c20_ctx->tag_len; | 171 | return in_len + c20_ctx->tag_len; |
173 | } | 172 | } |
174 | 173 | ||
175 | CRYPTO_poly1305_finish(&poly1305, out + in_len); | 174 | CRYPTO_poly1305_finish(&poly1305, out + in_len); |
176 | return in_len + POLY1305_TAG_LEN; | 175 | return in_len + POLY1305_TAG_LEN; |
177 | } | 176 | } |
178 | 177 | ||
179 | static ssize_t aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, | 178 | static ssize_t |
180 | unsigned char *out, size_t max_out_len, | 179 | aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out, |
181 | const unsigned char *nonce, size_t nonce_len, | 180 | size_t max_out_len, const unsigned char *nonce, size_t nonce_len, |
182 | const unsigned char *in, size_t in_len, | 181 | const unsigned char *in, size_t in_len, const unsigned char *ad, |
183 | const unsigned char *ad, size_t ad_len) | 182 | size_t ad_len) |
184 | { | 183 | { |
185 | const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; | 184 | const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; |
186 | unsigned char mac[POLY1305_TAG_LEN]; | 185 | unsigned char mac[POLY1305_TAG_LEN]; |
187 | unsigned char poly1305_key[32]; | 186 | unsigned char poly1305_key[32]; |
@@ -189,11 +188,10 @@ static ssize_t aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, | |||
189 | poly1305_state poly1305; | 188 | poly1305_state poly1305; |
190 | const uint64_t in_len_64 = in_len; | 189 | const uint64_t in_len_64 = in_len; |
191 | 190 | ||
192 | if (in_len < c20_ctx->tag_len) | 191 | if (in_len < c20_ctx->tag_len) { |
193 | { | ||
194 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_BAD_DECRYPT); | 192 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_BAD_DECRYPT); |
195 | return -1; | 193 | return -1; |
196 | } | 194 | } |
197 | 195 | ||
198 | /* The underlying ChaCha implementation may not overflow the block | 196 | /* The underlying ChaCha implementation may not overflow the block |
199 | * counter into the second counter word. Therefore we disallow | 197 | * counter into the second counter word. Therefore we disallow |
@@ -202,46 +200,44 @@ static ssize_t aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, | |||
202 | * 32-bits and this produces a warning because it's always false. | 200 | * 32-bits and this produces a warning because it's always false. |
203 | * Casting to uint64_t inside the conditional is not sufficient to stop | 201 | * Casting to uint64_t inside the conditional is not sufficient to stop |
204 | * the warning. */ | 202 | * the warning. */ |
205 | if (in_len_64 >= (1ull << 32)*64-64) | 203 | if (in_len_64 >= (1ull << 32)*64 - 64) { |
206 | { | ||
207 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_TOO_LARGE); | 204 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_TOO_LARGE); |
208 | return -1; | 205 | return -1; |
209 | } | 206 | } |
210 | 207 | ||
211 | if (nonce_len != CHACHA20_NONCE_LEN) | 208 | if (nonce_len != CHACHA20_NONCE_LEN) { |
212 | { | ||
213 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_IV_TOO_LARGE); | 209 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_IV_TOO_LARGE); |
214 | return -1; | 210 | return -1; |
215 | } | 211 | } |
216 | 212 | ||
217 | out_len = in_len - c20_ctx->tag_len; | 213 | out_len = in_len - c20_ctx->tag_len; |
218 | 214 | ||
219 | if (max_out_len < out_len) | 215 | if (max_out_len < out_len) { |
220 | { | 216 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, |
221 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_BUFFER_TOO_SMALL); | 217 | EVP_R_BUFFER_TOO_SMALL); |
222 | return -1; | 218 | return -1; |
223 | } | 219 | } |
224 | 220 | ||
225 | memset(poly1305_key, 0, sizeof(poly1305_key)); | 221 | memset(poly1305_key, 0, sizeof(poly1305_key)); |
226 | CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), c20_ctx->key, nonce, 0); | 222 | CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), |
223 | c20_ctx->key, nonce, 0); | ||
227 | 224 | ||
228 | CRYPTO_poly1305_init(&poly1305, poly1305_key); | 225 | CRYPTO_poly1305_init(&poly1305, poly1305_key); |
229 | poly1305_update_with_length(&poly1305, ad, ad_len); | 226 | poly1305_update_with_length(&poly1305, ad, ad_len); |
230 | poly1305_update_with_length(&poly1305, in, out_len); | 227 | poly1305_update_with_length(&poly1305, in, out_len); |
231 | CRYPTO_poly1305_finish(&poly1305, mac); | 228 | CRYPTO_poly1305_finish(&poly1305, mac); |
232 | 229 | ||
233 | if (CRYPTO_memcmp(mac, in + out_len, c20_ctx->tag_len) != 0) | 230 | if (CRYPTO_memcmp(mac, in + out_len, c20_ctx->tag_len) != 0) { |
234 | { | ||
235 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_BAD_DECRYPT); | 231 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_BAD_DECRYPT); |
236 | return -1; | 232 | return -1; |
237 | } | 233 | } |
238 | 234 | ||
239 | CRYPTO_chacha_20(out, in, out_len, c20_ctx->key, nonce, 1); | 235 | CRYPTO_chacha_20(out, in, out_len, c20_ctx->key, nonce, 1); |
236 | |||
240 | return out_len; | 237 | return out_len; |
241 | } | 238 | } |
242 | 239 | ||
243 | static const EVP_AEAD aead_chacha20_poly1305 = | 240 | static const EVP_AEAD aead_chacha20_poly1305 = { |
244 | { | ||
245 | 32, /* key len */ | 241 | 32, /* key len */ |
246 | CHACHA20_NONCE_LEN, /* nonce len */ | 242 | CHACHA20_NONCE_LEN, /* nonce len */ |
247 | POLY1305_TAG_LEN, /* overhead */ | 243 | POLY1305_TAG_LEN, /* overhead */ |
@@ -251,11 +247,12 @@ static const EVP_AEAD aead_chacha20_poly1305 = | |||
251 | aead_chacha20_poly1305_cleanup, | 247 | aead_chacha20_poly1305_cleanup, |
252 | aead_chacha20_poly1305_seal, | 248 | aead_chacha20_poly1305_seal, |
253 | aead_chacha20_poly1305_open, | 249 | aead_chacha20_poly1305_open, |
254 | }; | 250 | }; |
255 | 251 | ||
256 | const EVP_AEAD *EVP_aead_chacha20_poly1305() | 252 | const EVP_AEAD * |
257 | { | 253 | EVP_aead_chacha20_poly1305() |
254 | { | ||
258 | return &aead_chacha20_poly1305; | 255 | return &aead_chacha20_poly1305; |
259 | } | 256 | } |
260 | 257 | ||
261 | #endif /* !OPENSSL_NO_CHACHA && !OPENSSL_NO_POLY1305 */ | 258 | #endif /* !OPENSSL_NO_CHACHA && !OPENSSL_NO_POLY1305 */ |
diff --git a/src/lib/libssl/src/crypto/evp/e_chacha20poly1305.c b/src/lib/libssl/src/crypto/evp/e_chacha20poly1305.c index 9df6b7c453..6e4a3f507a 100644 --- a/src/lib/libssl/src/crypto/evp/e_chacha20poly1305.c +++ b/src/lib/libssl/src/crypto/evp/e_chacha20poly1305.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * are met: | 6 | * are met: |
7 | * | 7 | * |
8 | * 1. Redistributions of source code must retain the above copyright | 8 | * 1. Redistributions of source code must retain the above copyright |
9 | * notice, this list of conditions and the following disclaimer. | 9 | * notice, this list of conditions and the following disclaimer. |
10 | * | 10 | * |
11 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
12 | * notice, this list of conditions and the following disclaimer in | 12 | * notice, this list of conditions and the following disclaimer in |
@@ -63,24 +63,24 @@ | |||
63 | #define POLY1305_TAG_LEN 16 | 63 | #define POLY1305_TAG_LEN 16 |
64 | #define CHACHA20_NONCE_LEN 8 | 64 | #define CHACHA20_NONCE_LEN 8 |
65 | 65 | ||
66 | struct aead_chacha20_poly1305_ctx | 66 | struct aead_chacha20_poly1305_ctx { |
67 | { | ||
68 | unsigned char key[32]; | 67 | unsigned char key[32]; |
69 | unsigned char tag_len; | 68 | unsigned char tag_len; |
70 | }; | 69 | }; |
71 | 70 | ||
72 | static int aead_chacha20_poly1305_init(EVP_AEAD_CTX *ctx, const unsigned char *key, size_t key_len, size_t tag_len) | 71 | static int |
73 | { | 72 | aead_chacha20_poly1305_init(EVP_AEAD_CTX *ctx, const unsigned char *key, |
73 | size_t key_len, size_t tag_len) | ||
74 | { | ||
74 | struct aead_chacha20_poly1305_ctx *c20_ctx; | 75 | struct aead_chacha20_poly1305_ctx *c20_ctx; |
75 | 76 | ||
76 | if (tag_len == 0) | 77 | if (tag_len == 0) |
77 | tag_len = POLY1305_TAG_LEN; | 78 | tag_len = POLY1305_TAG_LEN; |
78 | 79 | ||
79 | if (tag_len > POLY1305_TAG_LEN) | 80 | if (tag_len > POLY1305_TAG_LEN) { |
80 | { | ||
81 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_INIT, EVP_R_TOO_LARGE); | 81 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_INIT, EVP_R_TOO_LARGE); |
82 | return 0; | 82 | return 0; |
83 | } | 83 | } |
84 | 84 | ||
85 | if (key_len != sizeof(c20_ctx->key)) | 85 | if (key_len != sizeof(c20_ctx->key)) |
86 | return 0; /* internal error - EVP_AEAD_CTX_init should catch this. */ | 86 | return 0; /* internal error - EVP_AEAD_CTX_init should catch this. */ |
@@ -94,38 +94,39 @@ static int aead_chacha20_poly1305_init(EVP_AEAD_CTX *ctx, const unsigned char *k | |||
94 | ctx->aead_state = c20_ctx; | 94 | ctx->aead_state = c20_ctx; |
95 | 95 | ||
96 | return 1; | 96 | return 1; |
97 | } | 97 | } |
98 | 98 | ||
99 | static void aead_chacha20_poly1305_cleanup(EVP_AEAD_CTX *ctx) | 99 | static void |
100 | { | 100 | aead_chacha20_poly1305_cleanup(EVP_AEAD_CTX *ctx) |
101 | { | ||
101 | struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; | 102 | struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; |
102 | OPENSSL_cleanse(c20_ctx->key, sizeof(c20_ctx->key)); | 103 | OPENSSL_cleanse(c20_ctx->key, sizeof(c20_ctx->key)); |
103 | OPENSSL_free(c20_ctx); | 104 | OPENSSL_free(c20_ctx); |
104 | } | 105 | } |
105 | 106 | ||
106 | static void poly1305_update_with_length(poly1305_state *poly1305, | 107 | static void |
107 | const unsigned char *data, size_t data_len) | 108 | poly1305_update_with_length(poly1305_state *poly1305, |
108 | { | 109 | const unsigned char *data, size_t data_len) |
110 | { | ||
109 | size_t j = data_len; | 111 | size_t j = data_len; |
110 | unsigned char length_bytes[8]; | 112 | unsigned char length_bytes[8]; |
111 | unsigned i; | 113 | unsigned i; |
112 | 114 | ||
113 | for (i = 0; i < sizeof(length_bytes); i++) | 115 | for (i = 0; i < sizeof(length_bytes); i++) { |
114 | { | ||
115 | length_bytes[i] = j; | 116 | length_bytes[i] = j; |
116 | j >>= 8; | 117 | j >>= 8; |
117 | } | 118 | } |
118 | 119 | ||
119 | CRYPTO_poly1305_update(poly1305, data, data_len); | 120 | CRYPTO_poly1305_update(poly1305, data, data_len); |
120 | CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes)); | 121 | CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes)); |
121 | } | 122 | } |
122 | 123 | ||
123 | static ssize_t aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, | 124 | static ssize_t |
124 | unsigned char *out, size_t max_out_len, | 125 | aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, |
125 | const unsigned char *nonce, size_t nonce_len, | 126 | size_t max_out_len, const unsigned char *nonce, size_t nonce_len, |
126 | const unsigned char *in, size_t in_len, | 127 | const unsigned char *in, size_t in_len, const unsigned char *ad, |
127 | const unsigned char *ad, size_t ad_len) | 128 | size_t ad_len) |
128 | { | 129 | { |
129 | const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; | 130 | const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; |
130 | unsigned char poly1305_key[32]; | 131 | unsigned char poly1305_key[32]; |
131 | poly1305_state poly1305; | 132 | poly1305_state poly1305; |
@@ -138,50 +139,48 @@ static ssize_t aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, | |||
138 | * 32-bits and this produces a warning because it's always false. | 139 | * 32-bits and this produces a warning because it's always false. |
139 | * Casting to uint64_t inside the conditional is not sufficient to stop | 140 | * Casting to uint64_t inside the conditional is not sufficient to stop |
140 | * the warning. */ | 141 | * the warning. */ |
141 | if (in_len_64 >= (1ull << 32)*64-64) | 142 | if (in_len_64 >= (1ull << 32)*64 - 64) { |
142 | { | ||
143 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, EVP_R_TOO_LARGE); | 143 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, EVP_R_TOO_LARGE); |
144 | return -1; | 144 | return -1; |
145 | } | 145 | } |
146 | 146 | ||
147 | if (max_out_len < in_len + c20_ctx->tag_len) | 147 | if (max_out_len < in_len + c20_ctx->tag_len) { |
148 | { | 148 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, |
149 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, EVP_R_BUFFER_TOO_SMALL); | 149 | EVP_R_BUFFER_TOO_SMALL); |
150 | return -1; | 150 | return -1; |
151 | } | 151 | } |
152 | 152 | ||
153 | if (nonce_len != CHACHA20_NONCE_LEN) | 153 | if (nonce_len != CHACHA20_NONCE_LEN) { |
154 | { | ||
155 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, EVP_R_IV_TOO_LARGE); | 154 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, EVP_R_IV_TOO_LARGE); |
156 | return -1; | 155 | return -1; |
157 | } | 156 | } |
158 | 157 | ||
159 | memset(poly1305_key, 0, sizeof(poly1305_key)); | 158 | memset(poly1305_key, 0, sizeof(poly1305_key)); |
160 | CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), c20_ctx->key, nonce, 0); | 159 | CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), |
160 | c20_ctx->key, nonce, 0); | ||
161 | 161 | ||
162 | CRYPTO_poly1305_init(&poly1305, poly1305_key); | 162 | CRYPTO_poly1305_init(&poly1305, poly1305_key); |
163 | poly1305_update_with_length(&poly1305, ad, ad_len); | 163 | poly1305_update_with_length(&poly1305, ad, ad_len); |
164 | CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1); | 164 | CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1); |
165 | poly1305_update_with_length(&poly1305, out, in_len); | 165 | poly1305_update_with_length(&poly1305, out, in_len); |
166 | 166 | ||
167 | if (c20_ctx->tag_len != POLY1305_TAG_LEN) | 167 | if (c20_ctx->tag_len != POLY1305_TAG_LEN) { |
168 | { | ||
169 | unsigned char tag[POLY1305_TAG_LEN]; | 168 | unsigned char tag[POLY1305_TAG_LEN]; |
170 | CRYPTO_poly1305_finish(&poly1305, tag); | 169 | CRYPTO_poly1305_finish(&poly1305, tag); |
171 | memcpy(out + in_len, tag, c20_ctx->tag_len); | 170 | memcpy(out + in_len, tag, c20_ctx->tag_len); |
172 | return in_len + c20_ctx->tag_len; | 171 | return in_len + c20_ctx->tag_len; |
173 | } | 172 | } |
174 | 173 | ||
175 | CRYPTO_poly1305_finish(&poly1305, out + in_len); | 174 | CRYPTO_poly1305_finish(&poly1305, out + in_len); |
176 | return in_len + POLY1305_TAG_LEN; | 175 | return in_len + POLY1305_TAG_LEN; |
177 | } | 176 | } |
178 | 177 | ||
179 | static ssize_t aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, | 178 | static ssize_t |
180 | unsigned char *out, size_t max_out_len, | 179 | aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out, |
181 | const unsigned char *nonce, size_t nonce_len, | 180 | size_t max_out_len, const unsigned char *nonce, size_t nonce_len, |
182 | const unsigned char *in, size_t in_len, | 181 | const unsigned char *in, size_t in_len, const unsigned char *ad, |
183 | const unsigned char *ad, size_t ad_len) | 182 | size_t ad_len) |
184 | { | 183 | { |
185 | const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; | 184 | const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; |
186 | unsigned char mac[POLY1305_TAG_LEN]; | 185 | unsigned char mac[POLY1305_TAG_LEN]; |
187 | unsigned char poly1305_key[32]; | 186 | unsigned char poly1305_key[32]; |
@@ -189,11 +188,10 @@ static ssize_t aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, | |||
189 | poly1305_state poly1305; | 188 | poly1305_state poly1305; |
190 | const uint64_t in_len_64 = in_len; | 189 | const uint64_t in_len_64 = in_len; |
191 | 190 | ||
192 | if (in_len < c20_ctx->tag_len) | 191 | if (in_len < c20_ctx->tag_len) { |
193 | { | ||
194 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_BAD_DECRYPT); | 192 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_BAD_DECRYPT); |
195 | return -1; | 193 | return -1; |
196 | } | 194 | } |
197 | 195 | ||
198 | /* The underlying ChaCha implementation may not overflow the block | 196 | /* The underlying ChaCha implementation may not overflow the block |
199 | * counter into the second counter word. Therefore we disallow | 197 | * counter into the second counter word. Therefore we disallow |
@@ -202,46 +200,44 @@ static ssize_t aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, | |||
202 | * 32-bits and this produces a warning because it's always false. | 200 | * 32-bits and this produces a warning because it's always false. |
203 | * Casting to uint64_t inside the conditional is not sufficient to stop | 201 | * Casting to uint64_t inside the conditional is not sufficient to stop |
204 | * the warning. */ | 202 | * the warning. */ |
205 | if (in_len_64 >= (1ull << 32)*64-64) | 203 | if (in_len_64 >= (1ull << 32)*64 - 64) { |
206 | { | ||
207 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_TOO_LARGE); | 204 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_TOO_LARGE); |
208 | return -1; | 205 | return -1; |
209 | } | 206 | } |
210 | 207 | ||
211 | if (nonce_len != CHACHA20_NONCE_LEN) | 208 | if (nonce_len != CHACHA20_NONCE_LEN) { |
212 | { | ||
213 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_IV_TOO_LARGE); | 209 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_IV_TOO_LARGE); |
214 | return -1; | 210 | return -1; |
215 | } | 211 | } |
216 | 212 | ||
217 | out_len = in_len - c20_ctx->tag_len; | 213 | out_len = in_len - c20_ctx->tag_len; |
218 | 214 | ||
219 | if (max_out_len < out_len) | 215 | if (max_out_len < out_len) { |
220 | { | 216 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, |
221 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_BUFFER_TOO_SMALL); | 217 | EVP_R_BUFFER_TOO_SMALL); |
222 | return -1; | 218 | return -1; |
223 | } | 219 | } |
224 | 220 | ||
225 | memset(poly1305_key, 0, sizeof(poly1305_key)); | 221 | memset(poly1305_key, 0, sizeof(poly1305_key)); |
226 | CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), c20_ctx->key, nonce, 0); | 222 | CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), |
223 | c20_ctx->key, nonce, 0); | ||
227 | 224 | ||
228 | CRYPTO_poly1305_init(&poly1305, poly1305_key); | 225 | CRYPTO_poly1305_init(&poly1305, poly1305_key); |
229 | poly1305_update_with_length(&poly1305, ad, ad_len); | 226 | poly1305_update_with_length(&poly1305, ad, ad_len); |
230 | poly1305_update_with_length(&poly1305, in, out_len); | 227 | poly1305_update_with_length(&poly1305, in, out_len); |
231 | CRYPTO_poly1305_finish(&poly1305, mac); | 228 | CRYPTO_poly1305_finish(&poly1305, mac); |
232 | 229 | ||
233 | if (CRYPTO_memcmp(mac, in + out_len, c20_ctx->tag_len) != 0) | 230 | if (CRYPTO_memcmp(mac, in + out_len, c20_ctx->tag_len) != 0) { |
234 | { | ||
235 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_BAD_DECRYPT); | 231 | EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_BAD_DECRYPT); |
236 | return -1; | 232 | return -1; |
237 | } | 233 | } |
238 | 234 | ||
239 | CRYPTO_chacha_20(out, in, out_len, c20_ctx->key, nonce, 1); | 235 | CRYPTO_chacha_20(out, in, out_len, c20_ctx->key, nonce, 1); |
236 | |||
240 | return out_len; | 237 | return out_len; |
241 | } | 238 | } |
242 | 239 | ||
243 | static const EVP_AEAD aead_chacha20_poly1305 = | 240 | static const EVP_AEAD aead_chacha20_poly1305 = { |
244 | { | ||
245 | 32, /* key len */ | 241 | 32, /* key len */ |
246 | CHACHA20_NONCE_LEN, /* nonce len */ | 242 | CHACHA20_NONCE_LEN, /* nonce len */ |
247 | POLY1305_TAG_LEN, /* overhead */ | 243 | POLY1305_TAG_LEN, /* overhead */ |
@@ -251,11 +247,12 @@ static const EVP_AEAD aead_chacha20_poly1305 = | |||
251 | aead_chacha20_poly1305_cleanup, | 247 | aead_chacha20_poly1305_cleanup, |
252 | aead_chacha20_poly1305_seal, | 248 | aead_chacha20_poly1305_seal, |
253 | aead_chacha20_poly1305_open, | 249 | aead_chacha20_poly1305_open, |
254 | }; | 250 | }; |
255 | 251 | ||
256 | const EVP_AEAD *EVP_aead_chacha20_poly1305() | 252 | const EVP_AEAD * |
257 | { | 253 | EVP_aead_chacha20_poly1305() |
254 | { | ||
258 | return &aead_chacha20_poly1305; | 255 | return &aead_chacha20_poly1305; |
259 | } | 256 | } |
260 | 257 | ||
261 | #endif /* !OPENSSL_NO_CHACHA && !OPENSSL_NO_POLY1305 */ | 258 | #endif /* !OPENSSL_NO_CHACHA && !OPENSSL_NO_POLY1305 */ |