Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(480)

Unified Diff: openssl/crypto/evp/e_aes.c

Issue 59083010: third_party/openssl: add ChaCha20+Poly1305 support. Base URL: https://chromium.googlesource.com/chromium/deps/openssl.git@master
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « openssl/crypto/crypto.h ('k') | openssl/crypto/evp/e_chacha20poly1305.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: openssl/crypto/evp/e_aes.c
diff --git a/openssl/crypto/evp/e_aes.c b/openssl/crypto/evp/e_aes.c
index 1bfb5d92b340172c8e97ec8d391b9d3e757b60a7..69165a2d1af2b0cd1d4d5f488b95905675b309a1 100644
--- a/openssl/crypto/evp/e_aes.c
+++ b/openssl/crypto/evp/e_aes.c
@@ -814,44 +814,45 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
}
}
-static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
- const unsigned char *iv, int enc)
+static ctr128_f aes_gcm_set_key(AES_KEY *aes_key, GCM128_CONTEXT *gcm_ctx,
+ const unsigned char *key, size_t key_len)
{
- EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
- if (!iv && !key)
- return 1;
- if (key)
- { do {
#ifdef BSAES_CAPABLE
if (BSAES_CAPABLE)
{
- AES_set_encrypt_key(key,ctx->key_len*8,&gctx->ks);
- CRYPTO_gcm128_init(&gctx->gcm,&gctx->ks,
+ AES_set_encrypt_key(key,key_len*8,aes_key);
+ CRYPTO_gcm128_init(gcm_ctx,aes_key,
(block128_f)AES_encrypt);
- gctx->ctr = (ctr128_f)bsaes_ctr32_encrypt_blocks;
- break;
+ return (ctr128_f)bsaes_ctr32_encrypt_blocks;
}
- else
#endif
#ifdef VPAES_CAPABLE
if (VPAES_CAPABLE)
{
- vpaes_set_encrypt_key(key,ctx->key_len*8,&gctx->ks);
- CRYPTO_gcm128_init(&gctx->gcm,&gctx->ks,
+ vpaes_set_encrypt_key(key,key_len*8,aes_key);
+ CRYPTO_gcm128_init(gcm_ctx,aes_key,
(block128_f)vpaes_encrypt);
- gctx->ctr = NULL;
- break;
+ return NULL;
}
#endif
- AES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks);
- CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, (block128_f)AES_encrypt);
+ AES_set_encrypt_key(key, key_len*8, aes_key);
+ CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)AES_encrypt);
#ifdef AES_CTR_ASM
- gctx->ctr = (ctr128_f)AES_ctr32_encrypt;
+ return (ctr128_f)AES_ctr32_encrypt;
#else
- gctx->ctr = NULL;
+ return NULL;
#endif
- } while (0);
+ }
+static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+ {
+ EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
+ if (!iv && !key)
+ return 1;
+ if (key)
+ {
+ gctx->ctr = aes_gcm_set_key(&gctx->ks, &gctx->gcm, key, ctx->key_len);
/* If we have an iv can set it directly, otherwise use
* saved IV.
*/
@@ -1310,5 +1311,176 @@ BLOCK_CIPHER_custom(NID_aes,128,1,12,ccm,CCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS)
BLOCK_CIPHER_custom(NID_aes,192,1,12,ccm,CCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS)
BLOCK_CIPHER_custom(NID_aes,256,1,12,ccm,CCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS)
+#define EVP_AEAD_AES_128_GCM_TAG_LEN 16
+
+struct aead_aes_128_gcm_ctx {
+ union { double align; AES_KEY ks; } ks;
+ GCM128_CONTEXT gcm;
+ ctr128_f ctr;
+ unsigned char tag_len;
+};
+
+static int aead_aes_128_gcm_init(EVP_AEAD_CTX *ctx,
+ const unsigned char *key, size_t key_len, size_t tag_len)
+ {
+ struct aead_aes_128_gcm_ctx *gcm_ctx;
+
+ if (key_len*8 != 128)
+ {
+ EVPerr(EVP_F_AEAD_AES_128_GCM_INIT, EVP_R_BAD_KEY_LENGTH);
+ return 0; /* EVP_AEAD_CTX_init should catch this. */
+ }
+
+ if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH)
+ tag_len = EVP_AEAD_AES_128_GCM_TAG_LEN;
+
+ if (tag_len > EVP_AEAD_AES_128_GCM_TAG_LEN)
+ {
+ EVPerr(EVP_F_AEAD_AES_128_GCM_INIT, EVP_R_TAG_TOO_LARGE);
+ return 0;
+ }
+
+ gcm_ctx = OPENSSL_malloc(sizeof(struct aead_aes_128_gcm_ctx));
+ if (gcm_ctx == NULL)
+ return 0;
+
+#ifdef AESNI_CAPABLE
+ if (AESNI_CAPABLE)
+ {
+ aesni_set_encrypt_key(key, key_len * 8, &gcm_ctx->ks.ks);
+ CRYPTO_gcm128_init(&gcm_ctx->gcm, &gcm_ctx->ks.ks,
+ (block128_f)aesni_encrypt);
+ gcm_ctx->ctr = (ctr128_f) aesni_ctr32_encrypt_blocks;
+ }
+ else
+#endif
+ {
+ gcm_ctx->ctr = aes_gcm_set_key(&gcm_ctx->ks.ks, &gcm_ctx->gcm,
+ key, key_len);
+ }
+ gcm_ctx->tag_len = tag_len;
+ ctx->aead_state = gcm_ctx;
+
+ return 1;
+ }
+
+static void aead_aes_128_gcm_cleanup(EVP_AEAD_CTX *ctx)
+ {
+ struct aead_aes_128_gcm_ctx *gcm_ctx = ctx->aead_state;
+ OPENSSL_free(gcm_ctx);
+ }
+
+static ssize_t aead_aes_128_gcm_seal(const EVP_AEAD_CTX *ctx,
+ unsigned char *out, size_t max_out_len,
+ const unsigned char *nonce, size_t nonce_len,
+ const unsigned char *in, size_t in_len,
+ const unsigned char *ad, size_t ad_len)
+ {
+ size_t bulk = 0;
+ const struct aead_aes_128_gcm_ctx *gcm_ctx = ctx->aead_state;
+ GCM128_CONTEXT gcm;
+
+ if (max_out_len < in_len + gcm_ctx->tag_len)
+ {
+ EVPerr(EVP_F_AEAD_AES_128_GCM_SEAL, EVP_R_BUFFER_TOO_SMALL);
+ return -1;
+ }
+
+ memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm));
+ CRYPTO_gcm128_setiv(&gcm, nonce, nonce_len);
+
+ if (ad_len > 0 && CRYPTO_gcm128_aad(&gcm, ad, ad_len))
+ return -1;
+
+ if (gcm_ctx->ctr)
+ {
+ if (CRYPTO_gcm128_encrypt_ctr32(&gcm, in + bulk, out + bulk,
+ in_len - bulk, gcm_ctx->ctr))
+ return -1;
+ }
+ else
+ {
+ if (CRYPTO_gcm128_encrypt(&gcm, in + bulk, out + bulk,
+ in_len - bulk))
+ return -1;
+ }
+
+ CRYPTO_gcm128_tag(&gcm, out + in_len, gcm_ctx->tag_len);
+ return in_len + gcm_ctx->tag_len;
+ }
+
+static ssize_t aead_aes_128_gcm_open(const EVP_AEAD_CTX *ctx,
+ unsigned char *out, size_t max_out_len,
+ const unsigned char *nonce, size_t nonce_len,
+ const unsigned char *in, size_t in_len,
+ const unsigned char *ad, size_t ad_len)
+ {
+ size_t bulk = 0;
+ const struct aead_aes_128_gcm_ctx *gcm_ctx = ctx->aead_state;
+ unsigned char tag[EVP_AEAD_AES_128_GCM_TAG_LEN];
+ size_t out_len;
+ GCM128_CONTEXT gcm;
+
+ if (in_len < gcm_ctx->tag_len)
+ {
+ EVPerr(EVP_F_AEAD_AES_128_GCM_OPEN, EVP_R_BAD_DECRYPT);
+ return -1;
+ }
+
+ out_len = in_len - gcm_ctx->tag_len;
+
+ if (max_out_len < out_len)
+ {
+ EVPerr(EVP_F_AEAD_AES_128_GCM_OPEN, EVP_R_BUFFER_TOO_SMALL);
+ return -1;
+ }
+
+ memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm));
+ CRYPTO_gcm128_setiv(&gcm, nonce, nonce_len);
+
+ if (CRYPTO_gcm128_aad(&gcm, ad, ad_len))
+ return -1;
+
+ if (gcm_ctx->ctr)
+ {
+ if (CRYPTO_gcm128_decrypt_ctr32(&gcm, in + bulk, out + bulk,
+ in_len-bulk-gcm_ctx->tag_len,
+ gcm_ctx->ctr))
+ return -1;
+ }
+ else
+ {
+ if (CRYPTO_gcm128_decrypt(&gcm, in + bulk, out + bulk,
+ in_len - bulk - gcm_ctx->tag_len))
+ return -1;
+ }
+
+ CRYPTO_gcm128_tag(&gcm, tag, gcm_ctx->tag_len);
+ if (CRYPTO_memcmp(tag, in + out_len, gcm_ctx->tag_len) != 0)
+ {
+ EVPerr(EVP_F_AEAD_AES_128_GCM_OPEN, EVP_R_BAD_DECRYPT);
+ return -1;
+ }
+
+ return out_len;
+ }
+
+static const EVP_AEAD aead_aes_128_gcm = {
+ 16, /* key len */
+ 12, /* nonce len */
+ EVP_AEAD_AES_128_GCM_TAG_LEN, /* overhead */
+ EVP_AEAD_AES_128_GCM_TAG_LEN, /* max tag length */
+
+ aead_aes_128_gcm_init,
+ aead_aes_128_gcm_cleanup,
+ aead_aes_128_gcm_seal,
+ aead_aes_128_gcm_open,
+};
+
+const EVP_AEAD *EVP_aead_aes_128_gcm()
+ {
+ return &aead_aes_128_gcm;
+ }
+
#endif
#endif
« no previous file with comments | « openssl/crypto/crypto.h ('k') | openssl/crypto/evp/e_chacha20poly1305.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698