--- sys/crypto/openssl/amd64/ossl_aes_gcm.c.orig +++ sys/crypto/openssl/amd64/ossl_aes_gcm.c @@ -459,7 +459,7 @@ size_t bulk = 0, res; int error; - res = (AES_BLOCK_LEN - ctx->gcm.mres) % AES_BLOCK_LEN; + res = MIN(len, (AES_BLOCK_LEN - ctx->gcm.mres) % AES_BLOCK_LEN); if ((error = gcm_encrypt(ctx, in, out, res)) != 0) return error; @@ -621,12 +621,12 @@ size_t bulk = 0, res; int error; - res = (AES_BLOCK_LEN - ctx->gcm.mres) % AES_BLOCK_LEN; + res = MIN(len, (AES_BLOCK_LEN - ctx->gcm.mres) % AES_BLOCK_LEN); if ((error = gcm_decrypt(ctx, in, out, res)) != 0) return error; - bulk = aesni_gcm_decrypt(in, out, len, &ctx->aes_ks, ctx->gcm.Yi.c, - ctx->gcm.Xi.u); + bulk = aesni_gcm_decrypt(in + res, out + res, len - res, &ctx->aes_ks, + ctx->gcm.Yi.c, ctx->gcm.Xi.u); ctx->gcm.len.u[1] += bulk; bulk += res; --- sys/crypto/openssl/ossl_aes.c.orig +++ sys/crypto/openssl/ossl_aes.c @@ -168,10 +168,9 @@ ossl_aes_gcm(struct ossl_session_cipher *s, struct cryptop *crp, const struct crypto_session_params *csp) { - struct ossl_cipher_context key; + struct ossl_gcm_context ctx; struct crypto_buffer_cursor cc_in, cc_out; unsigned char iv[AES_BLOCK_LEN], tag[AES_BLOCK_LEN]; - struct ossl_gcm_context *ctx; const unsigned char *inseg; unsigned char *outseg; size_t inlen, outlen, seglen; @@ -183,30 +182,37 @@ if (crp->crp_cipher_key != NULL) { if (encrypt) error = s->cipher->set_encrypt_key(crp->crp_cipher_key, - 8 * csp->csp_cipher_klen, &key); + 8 * csp->csp_cipher_klen, + (struct ossl_cipher_context *)&ctx); else error = s->cipher->set_decrypt_key(crp->crp_cipher_key, - 8 * csp->csp_cipher_klen, &key); + 8 * csp->csp_cipher_klen, + (struct ossl_cipher_context *)&ctx); if (error) return (error); - ctx = (struct ossl_gcm_context *)&key; } else if (encrypt) { - ctx = (struct ossl_gcm_context *)&s->enc_ctx; + memcpy(&ctx, &s->enc_ctx, sizeof(struct ossl_gcm_context)); } else { - ctx = (struct ossl_gcm_context *)&s->dec_ctx; + memcpy(&ctx, &s->dec_ctx, sizeof(struct ossl_gcm_context)); } crypto_read_iv(crp, iv); - ctx->ops->setiv(ctx, iv, csp->csp_ivlen); + ctx.ops->setiv(&ctx, iv, csp->csp_ivlen); - crypto_cursor_init(&cc_in, &crp->crp_buf); - crypto_cursor_advance(&cc_in, crp->crp_aad_start); - for (size_t alen = crp->crp_aad_length; alen > 0; alen -= seglen) { - inseg = crypto_cursor_segment(&cc_in, &inlen); - seglen = MIN(alen, inlen); - if (ctx->ops->aad(ctx, inseg, seglen) != 0) + if (crp->crp_aad != NULL) { + if (ctx.ops->aad(&ctx, crp->crp_aad, crp->crp_aad_length) != 0) return (EINVAL); - crypto_cursor_advance(&cc_in, seglen); + } else { + crypto_cursor_init(&cc_in, &crp->crp_buf); + crypto_cursor_advance(&cc_in, crp->crp_aad_start); + for (size_t alen = crp->crp_aad_length; alen > 0; + alen -= seglen) { + inseg = crypto_cursor_segment(&cc_in, &inlen); + seglen = MIN(alen, inlen); + if (ctx.ops->aad(&ctx, inseg, seglen) != 0) + return (EINVAL); + crypto_cursor_advance(&cc_in, seglen); + } } crypto_cursor_init(&cc_in, &crp->crp_buf); @@ -224,10 +230,10 @@ seglen = MIN(plen, MIN(inlen, outlen)); if (encrypt) { - if (ctx->ops->encrypt(ctx, inseg, outseg, seglen) != 0) + if (ctx.ops->encrypt(&ctx, inseg, outseg, seglen) != 0) return (EINVAL); } else { - if (ctx->ops->decrypt(ctx, inseg, outseg, seglen) != 0) + if (ctx.ops->decrypt(&ctx, inseg, outseg, seglen) != 0) return (EINVAL); } @@ -237,18 +243,19 @@ error = 0; if (encrypt) { - ctx->ops->tag(ctx, tag, GMAC_DIGEST_LEN); + ctx.ops->tag(&ctx, tag, GMAC_DIGEST_LEN); crypto_copyback(crp, crp->crp_digest_start, GMAC_DIGEST_LEN, tag); } else { crypto_copydata(crp, crp->crp_digest_start, GMAC_DIGEST_LEN, tag); - if (ctx->ops->finish(ctx, tag, GMAC_DIGEST_LEN) != 0) + if (ctx.ops->finish(&ctx, tag, GMAC_DIGEST_LEN) != 0) error = EBADMSG; } explicit_bzero(iv, sizeof(iv)); explicit_bzero(tag, sizeof(tag)); + explicit_bzero(&ctx, sizeof(ctx)); return (error); }