diff options
| author | jsing <> | 2014-05-15 15:13:56 +0000 |
|---|---|---|
| committer | jsing <> | 2014-05-15 15:13:56 +0000 |
| commit | a3bd5f0d5b984c082b9ce36a8da16bb7c3f1ab7e (patch) | |
| tree | 4faa38278c62b9bbe0e7ded53414d5ae7564efa1 /src/lib/libc | |
| parent | 8a65f7cbd781f32dec36666d5741de0662a0a71f (diff) | |
| download | openbsd-a3bd5f0d5b984c082b9ce36a8da16bb7c3f1ab7e.tar.gz openbsd-a3bd5f0d5b984c082b9ce36a8da16bb7c3f1ab7e.tar.bz2 openbsd-a3bd5f0d5b984c082b9ce36a8da16bb7c3f1ab7e.zip | |
KNF.
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libcrypto/evp/e_chacha20poly1305.c | 137 |
1 files changed, 67 insertions, 70 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 */ |
