xref: /freebsd/crypto/openssl/providers/implementations/ciphers/cipher_aes_hw_rv64i.inc (revision e7be843b4a162e68651d3911f0357ed464915629)
1*e7be843bSPierre Pronchery/*
2*e7be843bSPierre Pronchery * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
3*e7be843bSPierre Pronchery *
4*e7be843bSPierre Pronchery * Licensed under the Apache License 2.0 (the "License").  You may not use
5*e7be843bSPierre Pronchery * this file except in compliance with the License.  You can obtain a copy
6*e7be843bSPierre Pronchery * in the file LICENSE in the source distribution or at
7*e7be843bSPierre Pronchery * https://www.openssl.org/source/license.html
8*e7be843bSPierre Pronchery */
9*e7be843bSPierre Pronchery
10*e7be843bSPierre Pronchery/*-
11*e7be843bSPierre Pronchery * RISC-V 64 ZKND ZKNE support for AES modes ecb, cbc, ofb, cfb, ctr.
12*e7be843bSPierre Pronchery * This file is included by cipher_aes_hw.c
13*e7be843bSPierre Pronchery */
14*e7be843bSPierre Pronchery
15*e7be843bSPierre Pronchery#define cipher_hw_rv64i_zknd_zkne_cbc    ossl_cipher_hw_generic_cbc
16*e7be843bSPierre Pronchery#define cipher_hw_rv64i_zknd_zkne_ecb    ossl_cipher_hw_generic_ecb
17*e7be843bSPierre Pronchery#define cipher_hw_rv64i_zknd_zkne_ofb128 ossl_cipher_hw_generic_ofb128
18*e7be843bSPierre Pronchery#define cipher_hw_rv64i_zknd_zkne_cfb128 ossl_cipher_hw_generic_cfb128
19*e7be843bSPierre Pronchery#define cipher_hw_rv64i_zknd_zkne_cfb8   ossl_cipher_hw_generic_cfb8
20*e7be843bSPierre Pronchery#define cipher_hw_rv64i_zknd_zkne_cfb1   ossl_cipher_hw_generic_cfb1
21*e7be843bSPierre Pronchery#define cipher_hw_rv64i_zknd_zkne_ctr    ossl_cipher_hw_generic_ctr
22*e7be843bSPierre Pronchery
23*e7be843bSPierre Proncherystatic int cipher_hw_rv64i_zknd_zkne_initkey(PROV_CIPHER_CTX *dat,
24*e7be843bSPierre Pronchery                                   const unsigned char *key, size_t keylen)
25*e7be843bSPierre Pronchery{
26*e7be843bSPierre Pronchery    int ret;
27*e7be843bSPierre Pronchery    PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
28*e7be843bSPierre Pronchery    AES_KEY *ks = &adat->ks.ks;
29*e7be843bSPierre Pronchery
30*e7be843bSPierre Pronchery    dat->ks = ks;
31*e7be843bSPierre Pronchery
32*e7be843bSPierre Pronchery    if ((dat->mode == EVP_CIPH_ECB_MODE || dat->mode == EVP_CIPH_CBC_MODE)
33*e7be843bSPierre Pronchery        && !dat->enc) {
34*e7be843bSPierre Pronchery        ret = rv64i_zknd_set_decrypt_key(key, keylen * 8, ks);
35*e7be843bSPierre Pronchery        dat->block = (block128_f) rv64i_zknd_decrypt;
36*e7be843bSPierre Pronchery        dat->stream.cbc = NULL;
37*e7be843bSPierre Pronchery    } else {
38*e7be843bSPierre Pronchery        ret = rv64i_zkne_set_encrypt_key(key, keylen * 8, ks);
39*e7be843bSPierre Pronchery        dat->block = (block128_f) rv64i_zkne_encrypt;
40*e7be843bSPierre Pronchery        dat->stream.cbc = NULL;
41*e7be843bSPierre Pronchery    }
42*e7be843bSPierre Pronchery
43*e7be843bSPierre Pronchery    if (ret < 0) {
44*e7be843bSPierre Pronchery        ERR_raise(ERR_LIB_PROV, PROV_R_KEY_SETUP_FAILED);
45*e7be843bSPierre Pronchery        return 0;
46*e7be843bSPierre Pronchery    }
47*e7be843bSPierre Pronchery
48*e7be843bSPierre Pronchery    return 1;
49*e7be843bSPierre Pronchery}
50*e7be843bSPierre Pronchery
51*e7be843bSPierre Pronchery/*-
52*e7be843bSPierre Pronchery * RISC-V RV64 ZVKNED support for AES modes ecb, cbc, ofb, cfb, ctr.
53*e7be843bSPierre Pronchery * This file is included by cipher_aes_hw.c
54*e7be843bSPierre Pronchery */
55*e7be843bSPierre Pronchery
56*e7be843bSPierre Pronchery#define cipher_hw_rv64i_zvkned_cbc    ossl_cipher_hw_generic_cbc
57*e7be843bSPierre Pronchery#define cipher_hw_rv64i_zvkned_ecb    ossl_cipher_hw_generic_ecb
58*e7be843bSPierre Pronchery#define cipher_hw_rv64i_zvkned_ofb128 ossl_cipher_hw_generic_ofb128
59*e7be843bSPierre Pronchery#define cipher_hw_rv64i_zvkned_cfb128 ossl_cipher_hw_generic_cfb128
60*e7be843bSPierre Pronchery#define cipher_hw_rv64i_zvkned_cfb8   ossl_cipher_hw_generic_cfb8
61*e7be843bSPierre Pronchery#define cipher_hw_rv64i_zvkned_cfb1   ossl_cipher_hw_generic_cfb1
62*e7be843bSPierre Pronchery#define cipher_hw_rv64i_zvkned_ctr    ossl_cipher_hw_generic_ctr
63*e7be843bSPierre Pronchery
64*e7be843bSPierre Proncherystatic int cipher_hw_rv64i_zvkned_initkey(PROV_CIPHER_CTX *dat,
65*e7be843bSPierre Pronchery                                          const unsigned char *key,
66*e7be843bSPierre Pronchery                                          size_t keylen)
67*e7be843bSPierre Pronchery{
68*e7be843bSPierre Pronchery    int ret;
69*e7be843bSPierre Pronchery    PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
70*e7be843bSPierre Pronchery    AES_KEY *ks = &adat->ks.ks;
71*e7be843bSPierre Pronchery
72*e7be843bSPierre Pronchery    dat->ks = ks;
73*e7be843bSPierre Pronchery
74*e7be843bSPierre Pronchery    /*
75*e7be843bSPierre Pronchery     * Zvkned only supports 128 and 256 bit keys for key schedule generation.
76*e7be843bSPierre Pronchery     * For AES-192 case, we could fallback to `AES_set_encrypt_key`.
77*e7be843bSPierre Pronchery     * All Zvkned-based implementations use the same `encrypt-key` scheduling
78*e7be843bSPierre Pronchery     * for both encryption and decryption.
79*e7be843bSPierre Pronchery     */
80*e7be843bSPierre Pronchery    if (keylen * 8 == 128 || keylen * 8 == 256) {
81*e7be843bSPierre Pronchery        ret = rv64i_zvkned_set_encrypt_key(key, keylen * 8, ks);
82*e7be843bSPierre Pronchery    } else {
83*e7be843bSPierre Pronchery        ret = AES_set_encrypt_key(key, keylen * 8, ks);
84*e7be843bSPierre Pronchery    }
85*e7be843bSPierre Pronchery
86*e7be843bSPierre Pronchery    if (dat->mode == EVP_CIPH_CBC_MODE) {
87*e7be843bSPierre Pronchery        if (dat->enc) {
88*e7be843bSPierre Pronchery            dat->stream.cbc = (cbc128_f) rv64i_zvkned_cbc_encrypt;
89*e7be843bSPierre Pronchery        } else {
90*e7be843bSPierre Pronchery            dat->stream.cbc = (cbc128_f) rv64i_zvkned_cbc_decrypt;
91*e7be843bSPierre Pronchery        }
92*e7be843bSPierre Pronchery    } else if (dat->mode == EVP_CIPH_CTR_MODE) {
93*e7be843bSPierre Pronchery        if (RISCV_HAS_ZVKB()) {
94*e7be843bSPierre Pronchery            dat->stream.ctr = (ctr128_f) rv64i_zvkb_zvkned_ctr32_encrypt_blocks;
95*e7be843bSPierre Pronchery        }
96*e7be843bSPierre Pronchery    } else if (dat->mode == EVP_CIPH_ECB_MODE) {
97*e7be843bSPierre Pronchery        if (dat->enc) {
98*e7be843bSPierre Pronchery            dat->stream.ecb = (ecb128_f) rv64i_zvkned_ecb_encrypt;
99*e7be843bSPierre Pronchery        } else {
100*e7be843bSPierre Pronchery            dat->stream.ecb = (ecb128_f) rv64i_zvkned_ecb_decrypt;
101*e7be843bSPierre Pronchery        }
102*e7be843bSPierre Pronchery    }
103*e7be843bSPierre Pronchery
104*e7be843bSPierre Pronchery    /* Zvkned supports aes-128/192/256 encryption and decryption. */
105*e7be843bSPierre Pronchery    if ((dat->mode == EVP_CIPH_ECB_MODE || dat->mode == EVP_CIPH_CBC_MODE) &&
106*e7be843bSPierre Pronchery        !dat->enc) {
107*e7be843bSPierre Pronchery        dat->block = (block128_f) rv64i_zvkned_decrypt;
108*e7be843bSPierre Pronchery    } else {
109*e7be843bSPierre Pronchery        dat->block = (block128_f) rv64i_zvkned_encrypt;
110*e7be843bSPierre Pronchery    }
111*e7be843bSPierre Pronchery
112*e7be843bSPierre Pronchery    if (ret < 0) {
113*e7be843bSPierre Pronchery        ERR_raise(ERR_LIB_PROV, PROV_R_KEY_SETUP_FAILED);
114*e7be843bSPierre Pronchery        return 0;
115*e7be843bSPierre Pronchery    }
116*e7be843bSPierre Pronchery
117*e7be843bSPierre Pronchery    return 1;
118*e7be843bSPierre Pronchery}
119*e7be843bSPierre Pronchery
120*e7be843bSPierre Pronchery#define PROV_CIPHER_HW_declare(mode)                                           \
121*e7be843bSPierre Proncherystatic const PROV_CIPHER_HW rv64i_zknd_zkne_##mode = {                         \
122*e7be843bSPierre Pronchery    cipher_hw_rv64i_zknd_zkne_initkey,                                         \
123*e7be843bSPierre Pronchery    cipher_hw_rv64i_zknd_zkne_##mode,                                          \
124*e7be843bSPierre Pronchery    cipher_hw_aes_copyctx                                                      \
125*e7be843bSPierre Pronchery};                                                                             \
126*e7be843bSPierre Proncherystatic const PROV_CIPHER_HW rv64i_zvkned_##mode = {                            \
127*e7be843bSPierre Pronchery    cipher_hw_rv64i_zvkned_initkey,                                            \
128*e7be843bSPierre Pronchery    cipher_hw_rv64i_zvkned_##mode,                                             \
129*e7be843bSPierre Pronchery    cipher_hw_aes_copyctx                                                      \
130*e7be843bSPierre Pronchery};
131*e7be843bSPierre Pronchery#define PROV_CIPHER_HW_select(mode)                                            \
132*e7be843bSPierre Proncheryif (RISCV_HAS_ZVKNED() && riscv_vlen() >= 128)                                 \
133*e7be843bSPierre Pronchery    return &rv64i_zvkned_##mode;                                               \
134*e7be843bSPierre Proncheryelse if (RISCV_HAS_ZKND_AND_ZKNE())                                            \
135*e7be843bSPierre Pronchery    return &rv64i_zknd_zkne_##mode;
136