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. */ if (iv == NULL && gctx->iv_set) iv = gctx->iv; if (iv) { CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); gctx->iv_set = 1; } gctx->key_set = 1; } else { /* If key set use IV, otherwise copy */ if (gctx->key_set) CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); else memcpy(gctx->iv, iv, gctx->ivlen); gctx->iv_set = 1; gctx->iv_gen = 0; } return 1; }
static int aead_aes_gcm_init(EVP_AEAD_CTX *ctx, const unsigned char *key, size_t key_len, size_t tag_len) { struct aead_aes_gcm_ctx *gcm_ctx; const size_t key_bits = key_len * 8; /* EVP_AEAD_CTX_init should catch this. */ if (key_bits != 128 && key_bits != 256) { EVPerr(EVP_F_AEAD_AES_GCM_INIT, EVP_R_BAD_KEY_LENGTH); return 0; } if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) tag_len = EVP_AEAD_AES_GCM_TAG_LEN; if (tag_len > EVP_AEAD_AES_GCM_TAG_LEN) { EVPerr(EVP_F_AEAD_AES_GCM_INIT, EVP_R_TAG_TOO_LARGE); return 0; } gcm_ctx = malloc(sizeof(struct aead_aes_gcm_ctx)); if (gcm_ctx == NULL) return 0; #ifdef AESNI_CAPABLE if (AESNI_CAPABLE) { aesni_set_encrypt_key(key, key_bits, &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 int aead_aes_gcm_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t tag_len) { struct aead_aes_gcm_ctx *gcm_ctx; const size_t key_bits = key_len * 8; if (key_bits != 128 && key_bits != 256) { OPENSSL_PUT_ERROR(CIPHER, aead_aes_gcm_init, CIPHER_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_GCM_TAG_LEN; } if (tag_len > EVP_AEAD_AES_GCM_TAG_LEN) { OPENSSL_PUT_ERROR(CIPHER, aead_aes_gcm_init, CIPHER_R_TAG_TOO_LARGE); return 0; } gcm_ctx = OPENSSL_malloc(sizeof(struct aead_aes_gcm_ctx)); if (gcm_ctx == NULL) { return 0; } 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 { 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; }