static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, const uint8_t *iv, int enc) { EVP_AES_GCM_CTX *gctx = ctx->cipher_data; if (!iv && !key) { return 1; } if (key) { OPENSSL_memset(&gctx->gcm, 0, sizeof(gctx->gcm)); gctx->ctr = aes_ctr_set_key(&gctx->ks.ks, &gctx->gcm.gcm_key, NULL, 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, &gctx->ks.ks, 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, &gctx->ks.ks, iv, gctx->ivlen); } else { OPENSSL_memcpy(gctx->iv, iv, gctx->ivlen); } gctx->iv_set = 1; gctx->iv_gen = 0; } return 1; }
static int aead_aes_ctr_hmac_sha256_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t tag_len) { struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx = (struct aead_aes_ctr_hmac_sha256_ctx *)&ctx->state; static const size_t hmac_key_len = 32; if (key_len < hmac_key_len) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH); return 0; // EVP_AEAD_CTX_init should catch this. } const size_t aes_key_len = key_len - hmac_key_len; if (aes_key_len != 16 && aes_key_len != 32) { OPENSSL_PUT_ERROR(CIPHER, 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_CTR_HMAC_SHA256_TAG_LEN; } if (tag_len > EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE); return 0; } aes_ctx->ctr = aes_ctr_set_key(&aes_ctx->ks.ks, NULL, &aes_ctx->block, key, aes_key_len); ctx->tag_len = tag_len; hmac_init(&aes_ctx->inner_init_state, &aes_ctx->outer_init_state, key + aes_key_len); return 1; }
static int aead_aes_ccm_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t tag_len, unsigned M, unsigned L) { assert(M == EVP_AEAD_max_overhead(ctx->aead)); assert(M == EVP_AEAD_max_tag_len(ctx->aead)); assert(15 - L == EVP_AEAD_nonce_length(ctx->aead)); if (key_len != EVP_AEAD_key_length(ctx->aead)) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH); return 0; // EVP_AEAD_CTX_init should catch this. } if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) { tag_len = M; } if (tag_len != M) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE); return 0; } struct aead_aes_ccm_ctx *ccm_ctx = (struct aead_aes_ccm_ctx *)&ctx->state; block128_f block; ctr128_f ctr = aes_ctr_set_key(&ccm_ctx->ks.ks, NULL, &block, key, key_len); ctx->tag_len = tag_len; if (!CRYPTO_ccm128_init(&ccm_ctx->ccm, &ccm_ctx->ks.ks, block, ctr, M, L)) { OPENSSL_PUT_ERROR(CIPHER, ERR_R_INTERNAL_ERROR); return 0; } return 1; }
int evp_aead_aes_gcm_init(void *ctx_buf, size_t ctx_buf_len, const uint8_t *key, size_t key_len) { aead_assert_init_preconditions(alignof(struct aead_aes_gcm_ctx), sizeof(struct aead_aes_gcm_ctx), ctx_buf, ctx_buf_len, key); struct aead_aes_gcm_ctx *gcm_ctx = ctx_buf; gcm_ctx->ctr = aes_ctr_set_key(&gcm_ctx->ks.ks, &gcm_ctx->gcm, NULL, key, key_len); return 1; }
static int aead_aes_gcm_init_impl(struct aead_aes_gcm_ctx *gcm_ctx, size_t *out_tag_len, const uint8_t *key, size_t key_len, size_t tag_len) { const size_t key_bits = key_len * 8; if (key_bits != 128 && key_bits != 256) { OPENSSL_PUT_ERROR(CIPHER, 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, CIPHER_R_TAG_TOO_LARGE); return 0; } gcm_ctx->ctr = aes_ctr_set_key(&gcm_ctx->ks.ks, &gcm_ctx->gcm_key, NULL, key, key_len); *out_tag_len = tag_len; return 1; }
static int aead_aes_ccm_bluetooth_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t tag_len) { if (key_len != 16) { OPENSSL_PUT_ERROR(CIPHER, 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_CCM_BLUETOOTH_TAG_LEN; } if (tag_len != EVP_AEAD_AES_CCM_BLUETOOTH_TAG_LEN) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE); return 0; } struct aead_aes_ccm_ctx *ccm_ctx = OPENSSL_malloc(sizeof(struct aead_aes_ccm_ctx)); if (ccm_ctx == NULL) { OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE); return 0; } block128_f block; ctr128_f ctr = aes_ctr_set_key(&ccm_ctx->ks.ks, NULL, &block, key, key_len); ctx->tag_len = tag_len; if (!CRYPTO_ccm128_init(&ccm_ctx->ccm, &ccm_ctx->ks.ks, block, ctr, tag_len, 15 - EVP_AEAD_AES_CCM_BLUETOOTH_NONCE_LEN)) { OPENSSL_PUT_ERROR(CIPHER, ERR_R_INTERNAL_ERROR); OPENSSL_free(ccm_ctx); return 0; } ctx->aead_state = ccm_ctx; return 1; }