1*b077aed3SPierre Pronchery /*
2*b077aed3SPierre Pronchery * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
3*b077aed3SPierre Pronchery *
4*b077aed3SPierre Pronchery * Licensed under the Apache License 2.0 (the "License"). You may not use
5*b077aed3SPierre Pronchery * this file except in compliance with the License. You can obtain a copy
6*b077aed3SPierre Pronchery * in the file LICENSE in the source distribution or at
7*b077aed3SPierre Pronchery * https://www.openssl.org/source/license.html
8*b077aed3SPierre Pronchery */
9*b077aed3SPierre Pronchery
10*b077aed3SPierre Pronchery /* Dispatch functions for AES GCM mode */
11*b077aed3SPierre Pronchery
12*b077aed3SPierre Pronchery /*
13*b077aed3SPierre Pronchery * This file uses the low level AES functions (which are deprecated for
14*b077aed3SPierre Pronchery * non-internal use) in order to implement provider AES ciphers.
15*b077aed3SPierre Pronchery */
16*b077aed3SPierre Pronchery #include "internal/deprecated.h"
17*b077aed3SPierre Pronchery
18*b077aed3SPierre Pronchery #include "cipher_aes_gcm.h"
19*b077aed3SPierre Pronchery
aes_gcm_initkey(PROV_GCM_CTX * ctx,const unsigned char * key,size_t keylen)20*b077aed3SPierre Pronchery static int aes_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key,
21*b077aed3SPierre Pronchery size_t keylen)
22*b077aed3SPierre Pronchery {
23*b077aed3SPierre Pronchery PROV_AES_GCM_CTX *actx = (PROV_AES_GCM_CTX *)ctx;
24*b077aed3SPierre Pronchery AES_KEY *ks = &actx->ks.ks;
25*b077aed3SPierre Pronchery
26*b077aed3SPierre Pronchery # ifdef HWAES_CAPABLE
27*b077aed3SPierre Pronchery if (HWAES_CAPABLE) {
28*b077aed3SPierre Pronchery # ifdef HWAES_ctr32_encrypt_blocks
29*b077aed3SPierre Pronchery GCM_HW_SET_KEY_CTR_FN(ks, HWAES_set_encrypt_key, HWAES_encrypt,
30*b077aed3SPierre Pronchery HWAES_ctr32_encrypt_blocks);
31*b077aed3SPierre Pronchery # else
32*b077aed3SPierre Pronchery GCM_HW_SET_KEY_CTR_FN(ks, HWAES_set_encrypt_key, HWAES_encrypt, NULL);
33*b077aed3SPierre Pronchery # endif /* HWAES_ctr32_encrypt_blocks */
34*b077aed3SPierre Pronchery } else
35*b077aed3SPierre Pronchery # endif /* HWAES_CAPABLE */
36*b077aed3SPierre Pronchery
37*b077aed3SPierre Pronchery # ifdef BSAES_CAPABLE
38*b077aed3SPierre Pronchery if (BSAES_CAPABLE) {
39*b077aed3SPierre Pronchery GCM_HW_SET_KEY_CTR_FN(ks, AES_set_encrypt_key, AES_encrypt,
40*b077aed3SPierre Pronchery ossl_bsaes_ctr32_encrypt_blocks);
41*b077aed3SPierre Pronchery } else
42*b077aed3SPierre Pronchery # endif /* BSAES_CAPABLE */
43*b077aed3SPierre Pronchery
44*b077aed3SPierre Pronchery # ifdef VPAES_CAPABLE
45*b077aed3SPierre Pronchery if (VPAES_CAPABLE) {
46*b077aed3SPierre Pronchery GCM_HW_SET_KEY_CTR_FN(ks, vpaes_set_encrypt_key, vpaes_encrypt, NULL);
47*b077aed3SPierre Pronchery } else
48*b077aed3SPierre Pronchery # endif /* VPAES_CAPABLE */
49*b077aed3SPierre Pronchery
50*b077aed3SPierre Pronchery {
51*b077aed3SPierre Pronchery # ifdef AES_CTR_ASM
52*b077aed3SPierre Pronchery GCM_HW_SET_KEY_CTR_FN(ks, AES_set_encrypt_key, AES_encrypt,
53*b077aed3SPierre Pronchery AES_ctr32_encrypt);
54*b077aed3SPierre Pronchery # else
55*b077aed3SPierre Pronchery GCM_HW_SET_KEY_CTR_FN(ks, AES_set_encrypt_key, AES_encrypt, NULL);
56*b077aed3SPierre Pronchery # endif /* AES_CTR_ASM */
57*b077aed3SPierre Pronchery }
58*b077aed3SPierre Pronchery ctx->key_set = 1;
59*b077aed3SPierre Pronchery return 1;
60*b077aed3SPierre Pronchery }
61*b077aed3SPierre Pronchery
generic_aes_gcm_cipher_update(PROV_GCM_CTX * ctx,const unsigned char * in,size_t len,unsigned char * out)62*b077aed3SPierre Pronchery static int generic_aes_gcm_cipher_update(PROV_GCM_CTX *ctx, const unsigned char *in,
63*b077aed3SPierre Pronchery size_t len, unsigned char *out)
64*b077aed3SPierre Pronchery {
65*b077aed3SPierre Pronchery if (ctx->enc) {
66*b077aed3SPierre Pronchery if (ctx->ctr != NULL) {
67*b077aed3SPierre Pronchery #if defined(AES_GCM_ASM)
68*b077aed3SPierre Pronchery size_t bulk = 0;
69*b077aed3SPierre Pronchery
70*b077aed3SPierre Pronchery if (len >= AES_GCM_ENC_BYTES && AES_GCM_ASM(ctx)) {
71*b077aed3SPierre Pronchery size_t res = (16 - ctx->gcm.mres) % 16;
72*b077aed3SPierre Pronchery
73*b077aed3SPierre Pronchery if (CRYPTO_gcm128_encrypt(&ctx->gcm, in, out, res))
74*b077aed3SPierre Pronchery return 0;
75*b077aed3SPierre Pronchery
76*b077aed3SPierre Pronchery bulk = AES_gcm_encrypt(in + res, out + res, len - res,
77*b077aed3SPierre Pronchery ctx->gcm.key,
78*b077aed3SPierre Pronchery ctx->gcm.Yi.c, ctx->gcm.Xi.u);
79*b077aed3SPierre Pronchery
80*b077aed3SPierre Pronchery ctx->gcm.len.u[1] += bulk;
81*b077aed3SPierre Pronchery bulk += res;
82*b077aed3SPierre Pronchery }
83*b077aed3SPierre Pronchery if (CRYPTO_gcm128_encrypt_ctr32(&ctx->gcm, in + bulk, out + bulk,
84*b077aed3SPierre Pronchery len - bulk, ctx->ctr))
85*b077aed3SPierre Pronchery return 0;
86*b077aed3SPierre Pronchery #else
87*b077aed3SPierre Pronchery if (CRYPTO_gcm128_encrypt_ctr32(&ctx->gcm, in, out, len, ctx->ctr))
88*b077aed3SPierre Pronchery return 0;
89*b077aed3SPierre Pronchery #endif /* AES_GCM_ASM */
90*b077aed3SPierre Pronchery } else {
91*b077aed3SPierre Pronchery if (CRYPTO_gcm128_encrypt(&ctx->gcm, in, out, len))
92*b077aed3SPierre Pronchery return 0;
93*b077aed3SPierre Pronchery }
94*b077aed3SPierre Pronchery } else {
95*b077aed3SPierre Pronchery if (ctx->ctr != NULL) {
96*b077aed3SPierre Pronchery #if defined(AES_GCM_ASM)
97*b077aed3SPierre Pronchery size_t bulk = 0;
98*b077aed3SPierre Pronchery
99*b077aed3SPierre Pronchery if (len >= AES_GCM_DEC_BYTES && AES_GCM_ASM(ctx)) {
100*b077aed3SPierre Pronchery size_t res = (16 - ctx->gcm.mres) % 16;
101*b077aed3SPierre Pronchery
102*b077aed3SPierre Pronchery if (CRYPTO_gcm128_decrypt(&ctx->gcm, in, out, res))
103*b077aed3SPierre Pronchery return -1;
104*b077aed3SPierre Pronchery
105*b077aed3SPierre Pronchery bulk = AES_gcm_decrypt(in + res, out + res, len - res,
106*b077aed3SPierre Pronchery ctx->gcm.key,
107*b077aed3SPierre Pronchery ctx->gcm.Yi.c, ctx->gcm.Xi.u);
108*b077aed3SPierre Pronchery
109*b077aed3SPierre Pronchery ctx->gcm.len.u[1] += bulk;
110*b077aed3SPierre Pronchery bulk += res;
111*b077aed3SPierre Pronchery }
112*b077aed3SPierre Pronchery if (CRYPTO_gcm128_decrypt_ctr32(&ctx->gcm, in + bulk, out + bulk,
113*b077aed3SPierre Pronchery len - bulk, ctx->ctr))
114*b077aed3SPierre Pronchery return 0;
115*b077aed3SPierre Pronchery #else
116*b077aed3SPierre Pronchery if (CRYPTO_gcm128_decrypt_ctr32(&ctx->gcm, in, out, len, ctx->ctr))
117*b077aed3SPierre Pronchery return 0;
118*b077aed3SPierre Pronchery #endif /* AES_GCM_ASM */
119*b077aed3SPierre Pronchery } else {
120*b077aed3SPierre Pronchery if (CRYPTO_gcm128_decrypt(&ctx->gcm, in, out, len))
121*b077aed3SPierre Pronchery return 0;
122*b077aed3SPierre Pronchery }
123*b077aed3SPierre Pronchery }
124*b077aed3SPierre Pronchery return 1;
125*b077aed3SPierre Pronchery }
126*b077aed3SPierre Pronchery
127*b077aed3SPierre Pronchery static const PROV_GCM_HW aes_gcm = {
128*b077aed3SPierre Pronchery aes_gcm_initkey,
129*b077aed3SPierre Pronchery ossl_gcm_setiv,
130*b077aed3SPierre Pronchery ossl_gcm_aad_update,
131*b077aed3SPierre Pronchery generic_aes_gcm_cipher_update,
132*b077aed3SPierre Pronchery ossl_gcm_cipher_final,
133*b077aed3SPierre Pronchery ossl_gcm_one_shot
134*b077aed3SPierre Pronchery };
135*b077aed3SPierre Pronchery
136*b077aed3SPierre Pronchery #if defined(S390X_aes_128_CAPABLE)
137*b077aed3SPierre Pronchery # include "cipher_aes_gcm_hw_s390x.inc"
138*b077aed3SPierre Pronchery #elif defined(AESNI_CAPABLE)
139*b077aed3SPierre Pronchery # include "cipher_aes_gcm_hw_aesni.inc"
140*b077aed3SPierre Pronchery #elif defined(SPARC_AES_CAPABLE)
141*b077aed3SPierre Pronchery # include "cipher_aes_gcm_hw_t4.inc"
142*b077aed3SPierre Pronchery #elif defined(AES_PMULL_CAPABLE) && defined(AES_GCM_ASM)
143*b077aed3SPierre Pronchery # include "cipher_aes_gcm_hw_armv8.inc"
144*b077aed3SPierre Pronchery #else
ossl_prov_aes_hw_gcm(size_t keybits)145*b077aed3SPierre Pronchery const PROV_GCM_HW *ossl_prov_aes_hw_gcm(size_t keybits)
146*b077aed3SPierre Pronchery {
147*b077aed3SPierre Pronchery return &aes_gcm;
148*b077aed3SPierre Pronchery }
149*b077aed3SPierre Pronchery #endif
150*b077aed3SPierre Pronchery
151