OpenCoverage

e_chacha20poly1305.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/libressl/src/crypto/evp/e_chacha20poly1305.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* $OpenBSD: e_chacha20poly1305.c,v 1.18 2017/08/28 17:48:02 jsing Exp $ */-
2-
3/*-
4 * Copyright (c) 2015 Reyk Floter <reyk@openbsd.org>-
5 * Copyright (c) 2014, Google Inc.-
6 *-
7 * Permission to use, copy, modify, and/or distribute this software for any-
8 * purpose with or without fee is hereby granted, provided that the above-
9 * copyright notice and this permission notice appear in all copies.-
10 *-
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES-
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF-
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY-
14 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES-
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION-
16 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN-
17 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.-
18 */-
19-
20#include <stdint.h>-
21#include <string.h>-
22-
23#include <openssl/opensslconf.h>-
24-
25#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)-
26-
27#include <openssl/err.h>-
28#include <openssl/evp.h>-
29#include <openssl/chacha.h>-
30#include <openssl/poly1305.h>-
31-
32#include "evp_locl.h"-
33-
34#define POLY1305_TAG_LEN 16-
35-
36#define CHACHA20_CONSTANT_LEN 4-
37#define CHACHA20_IV_LEN 8-
38#define CHACHA20_NONCE_LEN (CHACHA20_CONSTANT_LEN + CHACHA20_IV_LEN)-
39-
40struct aead_chacha20_poly1305_ctx {-
41 unsigned char key[32];-
42 unsigned char tag_len;-
43};-
44-
45static int-
46aead_chacha20_poly1305_init(EVP_AEAD_CTX *ctx, const unsigned char *key,-
47 size_t key_len, size_t tag_len)-
48{-
49 struct aead_chacha20_poly1305_ctx *c20_ctx;-
50-
51 if (tag_len == 0)
tag_len == 0Description
TRUEevaluated 68 times by 2 tests
Evaluated by:
  • ssltest
  • tlstest
FALSEevaluated 4 times by 1 test
Evaluated by:
  • aeadtest
4-68
52 tag_len = POLY1305_TAG_LEN;
executed 68 times by 2 tests: tag_len = 16;
Executed by:
  • ssltest
  • tlstest
68
53-
54 if (tag_len > POLY1305_TAG_LEN) {
tag_len > 16Description
TRUEnever evaluated
FALSEevaluated 72 times by 3 tests
Evaluated by:
  • aeadtest
  • ssltest
  • tlstest
0-72
55 EVPerror(EVP_R_TOO_LARGE);-
56 return 0;
never executed: return 0;
0
57 }-
58-
59 /* Internal error - EVP_AEAD_CTX_init should catch this. */-
60 if (key_len != sizeof(c20_ctx->key))
key_len != siz...(c20_ctx->key)Description
TRUEnever evaluated
FALSEevaluated 72 times by 3 tests
Evaluated by:
  • aeadtest
  • ssltest
  • tlstest
0-72
61 return 0;
never executed: return 0;
0
62-
63 c20_ctx = malloc(sizeof(struct aead_chacha20_poly1305_ctx));-
64 if (c20_ctx == NULL)
c20_ctx == ((void *)0)Description
TRUEnever evaluated
FALSEevaluated 72 times by 3 tests
Evaluated by:
  • aeadtest
  • ssltest
  • tlstest
0-72
65 return 0;
never executed: return 0;
0
66-
67 memcpy(&c20_ctx->key[0], key, key_len);-
68 c20_ctx->tag_len = tag_len;-
69 ctx->aead_state = c20_ctx;-
70-
71 return 1;
executed 72 times by 3 tests: return 1;
Executed by:
  • aeadtest
  • ssltest
  • tlstest
72
72}-
73-
74static void-
75aead_chacha20_poly1305_cleanup(EVP_AEAD_CTX *ctx)-
76{-
77 struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;-
78-
79 freezero(c20_ctx, sizeof(*c20_ctx));-
80}
executed 72 times by 3 tests: end of block
Executed by:
  • aeadtest
  • ssltest
  • tlstest
72
81-
82static void-
83poly1305_update_with_length(poly1305_state *poly1305,-
84 const unsigned char *data, size_t data_len)-
85{-
86 size_t j = data_len;-
87 unsigned char length_bytes[8];-
88 unsigned i;-
89-
90 for (i = 0; i < sizeof(length_bytes); i++) {
i < sizeof(length_bytes)Description
TRUEevaluated 2656 times by 3 tests
Evaluated by:
  • aeadtest
  • ssltest
  • tlstest
FALSEevaluated 332 times by 3 tests
Evaluated by:
  • aeadtest
  • ssltest
  • tlstest
332-2656
91 length_bytes[i] = j;-
92 j >>= 8;-
93 }
executed 2656 times by 3 tests: end of block
Executed by:
  • aeadtest
  • ssltest
  • tlstest
2656
94-
95 if (data != NULL)
data != ((void *)0)Description
TRUEnever evaluated
FALSEevaluated 332 times by 3 tests
Evaluated by:
  • aeadtest
  • ssltest
  • tlstest
0-332
96 CRYPTO_poly1305_update(poly1305, data, data_len);
never executed: CRYPTO_poly1305_update(poly1305, data, data_len);
0
97 CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes));-
98}
executed 332 times by 3 tests: end of block
Executed by:
  • aeadtest
  • ssltest
  • tlstest
332
99-
100static void-
101poly1305_update_with_pad16(poly1305_state *poly1305,-
102 const unsigned char *data, size_t data_len)-
103{-
104 static const unsigned char zero_pad16[16];-
105 size_t pad_len;-
106-
107 CRYPTO_poly1305_update(poly1305, data, data_len);-
108-
109 /* pad16() is defined in RFC 7539 2.8.1. */-
110 if ((pad_len = data_len % 16) == 0)
(pad_len = data_len % 16) == 0Description
TRUEevaluated 123 times by 3 tests
Evaluated by:
  • aeadtest
  • ssltest
  • tlstest
FALSEevaluated 209 times by 3 tests
Evaluated by:
  • aeadtest
  • ssltest
  • tlstest
123-209
111 return;
executed 123 times by 3 tests: return;
Executed by:
  • aeadtest
  • ssltest
  • tlstest
123
112-
113 CRYPTO_poly1305_update(poly1305, zero_pad16, 16 - pad_len);-
114}
executed 209 times by 3 tests: end of block
Executed by:
  • aeadtest
  • ssltest
  • tlstest
209
115-
116static int-
117aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out,-
118 size_t *out_len, size_t max_out_len, const unsigned char *nonce,-
119 size_t nonce_len, const unsigned char *in, size_t in_len,-
120 const unsigned char *ad, size_t ad_len)-
121{-
122 const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;-
123 unsigned char poly1305_key[32];-
124 poly1305_state poly1305;-
125 const unsigned char *iv;-
126 const uint64_t in_len_64 = in_len;-
127 uint64_t ctr;-
128-
129 /* The underlying ChaCha implementation may not overflow the block-
130 * counter into the second counter word. Therefore we disallow-
131 * individual operations that work on more than 2TB at a time.-
132 * in_len_64 is needed because, on 32-bit platforms, size_t is only-
133 * 32-bits and this produces a warning because it's always false.-
134 * Casting to uint64_t inside the conditional is not sufficient to stop-
135 * the warning. */-
136 if (in_len_64 >= (1ULL << 32) * 64 - 64) {
in_len_64 >= (... 32) * 64 - 64Description
TRUEnever evaluated
FALSEevaluated 98 times by 3 tests
Evaluated by:
  • aeadtest
  • ssltest
  • tlstest
0-98
137 EVPerror(EVP_R_TOO_LARGE);-
138 return 0;
never executed: return 0;
0
139 }-
140-
141 if (max_out_len < in_len + c20_ctx->tag_len) {
max_out_len < ...0_ctx->tag_lenDescription
TRUEnever evaluated
FALSEevaluated 98 times by 3 tests
Evaluated by:
  • aeadtest
  • ssltest
  • tlstest
0-98
142 EVPerror(EVP_R_BUFFER_TOO_SMALL);-
143 return 0;
never executed: return 0;
0
144 }-
145-
146 if (nonce_len != ctx->aead->nonce_len) {
nonce_len != c...ead->nonce_lenDescription
TRUEnever evaluated
FALSEevaluated 98 times by 3 tests
Evaluated by:
  • aeadtest
  • ssltest
  • tlstest
0-98
147 EVPerror(EVP_R_IV_TOO_LARGE);-
148 return 0;
never executed: return 0;
0
149 }-
150-
151 ctr = (uint64_t)(nonce[0] | nonce[1] << 8 |-
152 nonce[2] << 16 | nonce[3] << 24) << 32;-
153 iv = nonce + CHACHA20_CONSTANT_LEN;-
154-
155 memset(poly1305_key, 0, sizeof(poly1305_key));-
156 CRYPTO_chacha_20(poly1305_key, poly1305_key,-
157 sizeof(poly1305_key), c20_ctx->key, iv, ctr);-
158-
159 CRYPTO_poly1305_init(&poly1305, poly1305_key);-
160 poly1305_update_with_pad16(&poly1305, ad, ad_len);-
161 CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, iv, ctr + 1);-
162 poly1305_update_with_pad16(&poly1305, out, in_len);-
163 poly1305_update_with_length(&poly1305, NULL, ad_len);-
164 poly1305_update_with_length(&poly1305, NULL, in_len);-
165-
166 if (c20_ctx->tag_len != POLY1305_TAG_LEN) {
c20_ctx->tag_len != 16Description
TRUEnever evaluated
FALSEevaluated 98 times by 3 tests
Evaluated by:
  • aeadtest
  • ssltest
  • tlstest
0-98
167 unsigned char tag[POLY1305_TAG_LEN];-
168 CRYPTO_poly1305_finish(&poly1305, tag);-
169 memcpy(out + in_len, tag, c20_ctx->tag_len);-
170 *out_len = in_len + c20_ctx->tag_len;-
171 return 1;
never executed: return 1;
0
172 }-
173-
174 CRYPTO_poly1305_finish(&poly1305, out + in_len);-
175 *out_len = in_len + POLY1305_TAG_LEN;-
176 return 1;
executed 98 times by 3 tests: return 1;
Executed by:
  • aeadtest
  • ssltest
  • tlstest
98
177}-
178-
179static int-
180aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out,-
181 size_t *out_len, size_t max_out_len, const unsigned char *nonce,-
182 size_t nonce_len, const unsigned char *in, size_t in_len,-
183 const unsigned char *ad, size_t ad_len)-
184{-
185 const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;-
186 unsigned char mac[POLY1305_TAG_LEN];-
187 unsigned char poly1305_key[32];-
188 const unsigned char *iv = nonce;-
189 poly1305_state poly1305;-
190 const uint64_t in_len_64 = in_len;-
191 size_t plaintext_len;-
192 uint64_t ctr = 0;-
193-
194 if (in_len < c20_ctx->tag_len) {
in_len < c20_ctx->tag_lenDescription
TRUEnever evaluated
FALSEevaluated 68 times by 3 tests
Evaluated by:
  • aeadtest
  • ssltest
  • tlstest
0-68
195 EVPerror(EVP_R_BAD_DECRYPT);-
196 return 0;
never executed: return 0;
0
197 }-
198-
199 /* The underlying ChaCha implementation may not overflow the block-
200 * counter into the second counter word. Therefore we disallow-
201 * individual operations that work on more than 2TB at a time.-
202 * in_len_64 is needed because, on 32-bit platforms, size_t is only-
203 * 32-bits and this produces a warning because it's always false.-
204 * Casting to uint64_t inside the conditional is not sufficient to stop-
205 * the warning. */-
206 if (in_len_64 >= (1ULL << 32) * 64 - 64) {
in_len_64 >= (... 32) * 64 - 64Description
TRUEnever evaluated
FALSEevaluated 68 times by 3 tests
Evaluated by:
  • aeadtest
  • ssltest
  • tlstest
0-68
207 EVPerror(EVP_R_TOO_LARGE);-
208 return 0;
never executed: return 0;
0
209 }-
210-
211 if (nonce_len != ctx->aead->nonce_len) {
nonce_len != c...ead->nonce_lenDescription
TRUEnever evaluated
FALSEevaluated 68 times by 3 tests
Evaluated by:
  • aeadtest
  • ssltest
  • tlstest
0-68
212 EVPerror(EVP_R_IV_TOO_LARGE);-
213 return 0;
never executed: return 0;
0
214 }-
215-
216 plaintext_len = in_len - c20_ctx->tag_len;-
217-
218 if (max_out_len < plaintext_len) {
max_out_len < plaintext_lenDescription
TRUEnever evaluated
FALSEevaluated 68 times by 3 tests
Evaluated by:
  • aeadtest
  • ssltest
  • tlstest
0-68
219 EVPerror(EVP_R_BUFFER_TOO_SMALL);-
220 return 0;
never executed: return 0;
0
221 }-
222-
223 ctr = (uint64_t)(nonce[0] | nonce[1] << 8 |-
224 nonce[2] << 16 | nonce[3] << 24) << 32;-
225 iv = nonce + CHACHA20_CONSTANT_LEN;-
226-
227 memset(poly1305_key, 0, sizeof(poly1305_key));-
228 CRYPTO_chacha_20(poly1305_key, poly1305_key,-
229 sizeof(poly1305_key), c20_ctx->key, iv, ctr);-
230-
231 CRYPTO_poly1305_init(&poly1305, poly1305_key);-
232 poly1305_update_with_pad16(&poly1305, ad, ad_len);-
233 poly1305_update_with_pad16(&poly1305, in, plaintext_len);-
234 poly1305_update_with_length(&poly1305, NULL, ad_len);-
235 poly1305_update_with_length(&poly1305, NULL, plaintext_len);-
236-
237 CRYPTO_poly1305_finish(&poly1305, mac);-
238-
239 if (timingsafe_memcmp(mac, in + plaintext_len, c20_ctx->tag_len) != 0) {
timingsafe_mem...>tag_len) != 0Description
TRUEevaluated 4 times by 1 test
Evaluated by:
  • aeadtest
FALSEevaluated 64 times by 3 tests
Evaluated by:
  • aeadtest
  • ssltest
  • tlstest
4-64
240 EVPerror(EVP_R_BAD_DECRYPT);-
241 return 0;
executed 4 times by 1 test: return 0;
Executed by:
  • aeadtest
4
242 }-
243-
244 CRYPTO_chacha_20(out, in, plaintext_len, c20_ctx->key, iv, ctr + 1);-
245 *out_len = plaintext_len;-
246 return 1;
executed 64 times by 3 tests: return 1;
Executed by:
  • aeadtest
  • ssltest
  • tlstest
64
247}-
248-
249/* RFC 7539 */-
250static const EVP_AEAD aead_chacha20_poly1305 = {-
251 .key_len = 32,-
252 .nonce_len = CHACHA20_NONCE_LEN,-
253 .overhead = POLY1305_TAG_LEN,-
254 .max_tag_len = POLY1305_TAG_LEN,-
255-
256 .init = aead_chacha20_poly1305_init,-
257 .cleanup = aead_chacha20_poly1305_cleanup,-
258 .seal = aead_chacha20_poly1305_seal,-
259 .open = aead_chacha20_poly1305_open,-
260};-
261-
262const EVP_AEAD *-
263EVP_aead_chacha20_poly1305()-
264{-
265 return &aead_chacha20_poly1305;
executed 38 times by 3 tests: return &aead_chacha20_poly1305;
Executed by:
  • aeadtest
  • ssltest
  • tlstest
38
266}-
267-
268#endif /* !OPENSSL_NO_CHACHA && !OPENSSL_NO_POLY1305 */-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.2.2