Path: blob/main/sys/crypto/openssl/amd64/ossl_aes_gcm_avx512.c
39483 views
/*1* Copyright 2010-2022 The OpenSSL Project Authors. All Rights Reserved.2* Copyright (c) 2021, Intel Corporation. All Rights Reserved.3*4* Licensed under the Apache License 2.0 (the "License"). You may not use5* this file except in compliance with the License. You can obtain a copy6* in the file LICENSE in the source distribution or at7* https://www.openssl.org/source/license.html8*/910/*11* This file contains an AES-GCM wrapper implementation from OpenSSL, using12* VAES extensions. It was ported from cipher_aes_gcm_hw_vaes_avx512.inc.13*/1415#include <sys/endian.h>16#include <sys/systm.h>1718#include <crypto/openssl/ossl.h>19#include <crypto/openssl/ossl_aes_gcm.h>20#include <crypto/openssl/ossl_cipher.h>2122#include <opencrypto/cryptodev.h>2324_Static_assert(25sizeof(struct ossl_gcm_context) <= sizeof(struct ossl_cipher_context),26"ossl_gcm_context too large");2728void aesni_set_encrypt_key(const void *key, int bits, void *ctx);2930static void31gcm_init(struct ossl_gcm_context *ctx, const void *key, size_t keylen)32{33KASSERT(keylen == 128 || keylen == 192 || keylen == 256,34("%s: invalid key length %zu", __func__, keylen));3536memset(&ctx->gcm, 0, sizeof(ctx->gcm));37memset(&ctx->aes_ks, 0, sizeof(ctx->aes_ks));38aesni_set_encrypt_key(key, keylen, &ctx->aes_ks);39ctx->ops->init(ctx, key, keylen);40}4142static void43gcm_tag(struct ossl_gcm_context *ctx, unsigned char *tag, size_t len)44{45(void)ctx->ops->finish(ctx, NULL, 0);46memcpy(tag, ctx->gcm.Xi.c, len);47}4849void ossl_gcm_gmult_avx512(uint64_t Xi[2], void *gcm128ctx);50void ossl_aes_gcm_init_avx512(const void *ks, void *gcm128ctx);51void ossl_aes_gcm_setiv_avx512(const void *ks, void *gcm128ctx,52const unsigned char *iv, size_t ivlen);53void ossl_aes_gcm_update_aad_avx512(void *gcm128ctx, const unsigned char *aad,54size_t len);55void ossl_aes_gcm_encrypt_avx512(const void *ks, void *gcm128ctx,56unsigned int *pblocklen, const unsigned char *in, size_t len,57unsigned char *out);58void ossl_aes_gcm_decrypt_avx512(const void *ks, void *gcm128ctx,59unsigned int *pblocklen, const unsigned char *in, size_t len,60unsigned char *out);61void ossl_aes_gcm_finalize_avx512(void *gcm128ctx, unsigned int pblocklen);6263static void64gcm_init_avx512(struct ossl_gcm_context *ctx, const void *key, size_t keylen)65{66ossl_aes_gcm_init_avx512(&ctx->aes_ks, &ctx->gcm);67}6869static void70gcm_setiv_avx512(struct ossl_gcm_context *ctx, const unsigned char *iv,71size_t len)72{73KASSERT(len == AES_GCM_IV_LEN,74("%s: invalid IV length %zu", __func__, len));7576ctx->gcm.Yi.u[0] = 0; /* Current counter */77ctx->gcm.Yi.u[1] = 0;78ctx->gcm.Xi.u[0] = 0; /* AAD hash */79ctx->gcm.Xi.u[1] = 0;80ctx->gcm.len.u[0] = 0; /* AAD length */81ctx->gcm.len.u[1] = 0; /* Message length */82ctx->gcm.ares = 0;83ctx->gcm.mres = 0;8485ossl_aes_gcm_setiv_avx512(&ctx->aes_ks, ctx, iv, len);86}8788static int89gcm_aad_avx512(struct ossl_gcm_context *ctx, const unsigned char *aad,90size_t len)91{92uint64_t alen = ctx->gcm.len.u[0];93size_t lenblks;94unsigned int ares;9596/* Bad sequence: call of AAD update after message processing */97if (ctx->gcm.len.u[1])98return -2;99100alen += len;101/* AAD is limited by 2^64 bits, thus 2^61 bytes */102if (alen > (1ull << 61) || (sizeof(len) == 8 && alen < len))103return -1;104ctx->gcm.len.u[0] = alen;105106ares = ctx->gcm.ares;107/* Partial AAD block left from previous AAD update calls */108if (ares > 0) {109/*110* Fill partial block buffer till full block111* (note, the hash is stored reflected)112*/113while (ares > 0 && len > 0) {114ctx->gcm.Xi.c[15 - ares] ^= *(aad++);115--len;116ares = (ares + 1) % AES_BLOCK_LEN;117}118/* Full block gathered */119if (ares == 0) {120ossl_gcm_gmult_avx512(ctx->gcm.Xi.u, ctx);121} else { /* no more AAD */122ctx->gcm.ares = ares;123return 0;124}125}126127/* Bulk AAD processing */128lenblks = len & ((size_t)(-AES_BLOCK_LEN));129if (lenblks > 0) {130ossl_aes_gcm_update_aad_avx512(ctx, aad, lenblks);131aad += lenblks;132len -= lenblks;133}134135/* Add remaining AAD to the hash (note, the hash is stored reflected) */136if (len > 0) {137ares = (unsigned int)len;138for (size_t i = 0; i < len; ++i)139ctx->gcm.Xi.c[15 - i] ^= aad[i];140}141142ctx->gcm.ares = ares;143144return 0;145}146147static int148_gcm_encrypt_avx512(struct ossl_gcm_context *ctx, const unsigned char *in,149unsigned char *out, size_t len, bool encrypt)150{151uint64_t mlen = ctx->gcm.len.u[1];152153mlen += len;154if (mlen > ((1ull << 36) - 32) || (sizeof(len) == 8 && mlen < len))155return -1;156157ctx->gcm.len.u[1] = mlen;158159/* Finalize GHASH(AAD) if AAD partial blocks left unprocessed */160if (ctx->gcm.ares > 0) {161ossl_gcm_gmult_avx512(ctx->gcm.Xi.u, ctx);162ctx->gcm.ares = 0;163}164165if (encrypt) {166ossl_aes_gcm_encrypt_avx512(&ctx->aes_ks, ctx, &ctx->gcm.mres,167in, len, out);168} else {169ossl_aes_gcm_decrypt_avx512(&ctx->aes_ks, ctx, &ctx->gcm.mres,170in, len, out);171}172173return 0;174}175176static int177gcm_encrypt_avx512(struct ossl_gcm_context *ctx, const unsigned char *in,178unsigned char *out, size_t len)179{180return _gcm_encrypt_avx512(ctx, in, out, len, true);181}182183static int184gcm_decrypt_avx512(struct ossl_gcm_context *ctx, const unsigned char *in,185unsigned char *out, size_t len)186{187return _gcm_encrypt_avx512(ctx, in, out, len, false);188}189190static int191gcm_finish_avx512(struct ossl_gcm_context *ctx, const unsigned char *tag,192size_t len)193{194unsigned int *res = &ctx->gcm.mres;195196/* Finalize AAD processing */197if (ctx->gcm.ares > 0)198res = &ctx->gcm.ares;199200ossl_aes_gcm_finalize_avx512(ctx, *res);201202ctx->gcm.ares = ctx->gcm.mres = 0;203204if (tag != NULL)205return timingsafe_bcmp(ctx->gcm.Xi.c, tag, len);206return 0;207}208209static const struct ossl_aes_gcm_ops gcm_ops_avx512 = {210.init = gcm_init_avx512,211.setiv = gcm_setiv_avx512,212.aad = gcm_aad_avx512,213.encrypt = gcm_encrypt_avx512,214.decrypt = gcm_decrypt_avx512,215.finish = gcm_finish_avx512,216.tag = gcm_tag,217};218219int ossl_aes_gcm_setkey_avx512(const unsigned char *key, int klen, void *_ctx);220221int222ossl_aes_gcm_setkey_avx512(const unsigned char *key, int klen,223void *_ctx)224{225struct ossl_gcm_context *ctx;226227ctx = _ctx;228ctx->ops = &gcm_ops_avx512;229gcm_init(ctx, key, klen);230return (0);231}232233234