1/*
2 * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License").  You may not use
5 * this file except in compliance with the License.  You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10/*-
11 * RISC-V 64 support for AES GCM.
12 * This file is included by cipher_aes_gcm_hw.c
13 */
14
15/*-
16 * RISC-V 64 ZKND and ZKNE support for AES GCM.
17 */
18static int rv64i_zknd_zkne_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key,
19                                       size_t keylen)
20{
21    PROV_AES_GCM_CTX *actx = (PROV_AES_GCM_CTX *)ctx;
22    AES_KEY *ks = &actx->ks.ks;
23    GCM_HW_SET_KEY_CTR_FN(ks, rv64i_zkne_set_encrypt_key, rv64i_zkne_encrypt,
24                          NULL);
25    return 1;
26}
27
28static const PROV_GCM_HW rv64i_zknd_zkne_gcm = {
29    rv64i_zknd_zkne_gcm_initkey,
30    ossl_gcm_setiv,
31    ossl_gcm_aad_update,
32    generic_aes_gcm_cipher_update,
33    ossl_gcm_cipher_final,
34    ossl_gcm_one_shot
35};
36
37/*-
38 * RISC-V RV64 ZVKNED support for AES GCM.
39 */
40static int rv64i_zvkned_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key,
41                                    size_t keylen)
42{
43    PROV_AES_GCM_CTX *actx = (PROV_AES_GCM_CTX *)ctx;
44    AES_KEY *ks = &actx->ks.ks;
45
46    /*
47     * Zvkned only supports 128 and 256 bit keys for key schedule generation.
48     * For AES-192 case, we could fallback to `AES_set_encrypt_key`.
49     */
50    if (keylen * 8 == 128 || keylen * 8 == 256) {
51        GCM_HW_SET_KEY_CTR_FN(ks, rv64i_zvkned_set_encrypt_key,
52                              rv64i_zvkned_encrypt, NULL);
53    } else {
54        GCM_HW_SET_KEY_CTR_FN(ks, AES_set_encrypt_key,
55                              rv64i_zvkned_encrypt, NULL);
56    }
57
58    return 1;
59}
60
61static const PROV_GCM_HW rv64i_zvkned_gcm = {
62    rv64i_zvkned_gcm_initkey,
63    ossl_gcm_setiv,
64    ossl_gcm_aad_update,
65    generic_aes_gcm_cipher_update,
66    ossl_gcm_cipher_final,
67    ossl_gcm_one_shot
68};
69
70/*-
71 * RISC-V RV64 ZVKB, ZVKG and ZVKNED support for AES GCM.
72 */
73static int rv64i_zvkb_zvkg_zvkned_gcm_initkey(PROV_GCM_CTX *ctx,
74                                              const unsigned char *key,
75                                              size_t keylen) {
76    PROV_AES_GCM_CTX *actx = (PROV_AES_GCM_CTX *)ctx;
77    AES_KEY *ks = &actx->ks.ks;
78
79    /*
80     * Zvkned only supports 128 and 256 bit keys for key schedule generation.
81     * For AES-192 case, we could fallback to `AES_set_encrypt_key`.
82     */
83    if (keylen * 8 == 128 || keylen * 8 == 256) {
84        GCM_HW_SET_KEY_CTR_FN(ks, rv64i_zvkned_set_encrypt_key,
85                              rv64i_zvkned_encrypt,
86                              rv64i_zvkb_zvkned_ctr32_encrypt_blocks);
87    } else {
88        GCM_HW_SET_KEY_CTR_FN(ks, AES_set_encrypt_key,
89                              rv64i_zvkned_encrypt,
90                              rv64i_zvkb_zvkned_ctr32_encrypt_blocks);
91    }
92
93    return 1;
94}
95
96static const PROV_GCM_HW rv64i_zvkb_zvkg_zvkned_gcm = {
97    rv64i_zvkb_zvkg_zvkned_gcm_initkey,
98    ossl_gcm_setiv,
99    ossl_gcm_aad_update,
100    generic_aes_gcm_cipher_update,
101    ossl_gcm_cipher_final,
102    ossl_gcm_one_shot
103};
104
105const PROV_GCM_HW *ossl_prov_aes_hw_gcm(size_t keybits) {
106    if (RISCV_HAS_ZVKNED()) {
107      if (RISCV_HAS_ZVKB() && RISCV_HAS_ZVKG() && riscv_vlen() >= 128) {
108        return &rv64i_zvkb_zvkg_zvkned_gcm;
109      }
110      return &rv64i_zvkned_gcm;
111    }
112
113    if (RISCV_HAS_ZKND_AND_ZKNE()) {
114      return &rv64i_zknd_zkne_gcm;
115    }
116
117    return &aes_gcm;
118}
119