1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci *
4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci */
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ci/*
11e1051a39Sopenharmony_ci * This file uses the low level AES functions (which are deprecated for
12e1051a39Sopenharmony_ci * non-internal use) in order to implement provider AES ciphers.
13e1051a39Sopenharmony_ci */
14e1051a39Sopenharmony_ci#include "internal/deprecated.h"
15e1051a39Sopenharmony_ci
16e1051a39Sopenharmony_ci#include "cipher_aes_xts.h"
17e1051a39Sopenharmony_ci
18e1051a39Sopenharmony_ci#define XTS_SET_KEY_FN(fn_set_enc_key, fn_set_dec_key,                         \
19e1051a39Sopenharmony_ci                       fn_block_enc, fn_block_dec,                             \
20e1051a39Sopenharmony_ci                       fn_stream_enc, fn_stream_dec) {                         \
21e1051a39Sopenharmony_ci    size_t bytes = keylen / 2;                                                 \
22e1051a39Sopenharmony_ci    size_t bits = bytes * 8;                                                   \
23e1051a39Sopenharmony_ci                                                                               \
24e1051a39Sopenharmony_ci    if (ctx->enc) {                                                            \
25e1051a39Sopenharmony_ci        fn_set_enc_key(key, bits, &xctx->ks1.ks);                              \
26e1051a39Sopenharmony_ci        xctx->xts.block1 = (block128_f)fn_block_enc;                           \
27e1051a39Sopenharmony_ci    } else {                                                                   \
28e1051a39Sopenharmony_ci        fn_set_dec_key(key, bits, &xctx->ks1.ks);                              \
29e1051a39Sopenharmony_ci        xctx->xts.block1 = (block128_f)fn_block_dec;                           \
30e1051a39Sopenharmony_ci    }                                                                          \
31e1051a39Sopenharmony_ci    fn_set_enc_key(key + bytes, bits, &xctx->ks2.ks);                          \
32e1051a39Sopenharmony_ci    xctx->xts.block2 = (block128_f)fn_block_enc;                               \
33e1051a39Sopenharmony_ci    xctx->xts.key1 = &xctx->ks1;                                               \
34e1051a39Sopenharmony_ci    xctx->xts.key2 = &xctx->ks2;                                               \
35e1051a39Sopenharmony_ci    xctx->stream = ctx->enc ? fn_stream_enc : fn_stream_dec;                   \
36e1051a39Sopenharmony_ci}
37e1051a39Sopenharmony_ci
38e1051a39Sopenharmony_cistatic int cipher_hw_aes_xts_generic_initkey(PROV_CIPHER_CTX *ctx,
39e1051a39Sopenharmony_ci                                             const unsigned char *key,
40e1051a39Sopenharmony_ci                                             size_t keylen)
41e1051a39Sopenharmony_ci{
42e1051a39Sopenharmony_ci    PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx;
43e1051a39Sopenharmony_ci    OSSL_xts_stream_fn stream_enc = NULL;
44e1051a39Sopenharmony_ci    OSSL_xts_stream_fn stream_dec = NULL;
45e1051a39Sopenharmony_ci
46e1051a39Sopenharmony_ci#ifdef AES_XTS_ASM
47e1051a39Sopenharmony_ci    stream_enc = AES_xts_encrypt;
48e1051a39Sopenharmony_ci    stream_dec = AES_xts_decrypt;
49e1051a39Sopenharmony_ci#endif /* AES_XTS_ASM */
50e1051a39Sopenharmony_ci
51e1051a39Sopenharmony_ci#ifdef HWAES_CAPABLE
52e1051a39Sopenharmony_ci    if (HWAES_CAPABLE) {
53e1051a39Sopenharmony_ci# ifdef HWAES_xts_encrypt
54e1051a39Sopenharmony_ci        stream_enc = HWAES_xts_encrypt;
55e1051a39Sopenharmony_ci# endif /* HWAES_xts_encrypt */
56e1051a39Sopenharmony_ci# ifdef HWAES_xts_decrypt
57e1051a39Sopenharmony_ci        stream_dec = HWAES_xts_decrypt;
58e1051a39Sopenharmony_ci# endif /* HWAES_xts_decrypt */
59e1051a39Sopenharmony_ci        XTS_SET_KEY_FN(HWAES_set_encrypt_key, HWAES_set_decrypt_key,
60e1051a39Sopenharmony_ci                       HWAES_encrypt, HWAES_decrypt,
61e1051a39Sopenharmony_ci                       stream_enc, stream_dec);
62e1051a39Sopenharmony_ci        return 1;
63e1051a39Sopenharmony_ci    } else
64e1051a39Sopenharmony_ci#endif /* HWAES_CAPABLE */
65e1051a39Sopenharmony_ci
66e1051a39Sopenharmony_ci#ifdef BSAES_CAPABLE
67e1051a39Sopenharmony_ci    if (BSAES_CAPABLE) {
68e1051a39Sopenharmony_ci        stream_enc = ossl_bsaes_xts_encrypt;
69e1051a39Sopenharmony_ci        stream_dec = ossl_bsaes_xts_decrypt;
70e1051a39Sopenharmony_ci    } else
71e1051a39Sopenharmony_ci#endif /* BSAES_CAPABLE */
72e1051a39Sopenharmony_ci#ifdef VPAES_CAPABLE
73e1051a39Sopenharmony_ci    if (VPAES_CAPABLE) {
74e1051a39Sopenharmony_ci        XTS_SET_KEY_FN(vpaes_set_encrypt_key, vpaes_set_decrypt_key,
75e1051a39Sopenharmony_ci                       vpaes_encrypt, vpaes_decrypt, stream_enc, stream_dec);
76e1051a39Sopenharmony_ci        return 1;
77e1051a39Sopenharmony_ci    } else
78e1051a39Sopenharmony_ci#endif /* VPAES_CAPABLE */
79e1051a39Sopenharmony_ci    {
80e1051a39Sopenharmony_ci        (void)0;
81e1051a39Sopenharmony_ci    }
82e1051a39Sopenharmony_ci    {
83e1051a39Sopenharmony_ci        XTS_SET_KEY_FN(AES_set_encrypt_key, AES_set_decrypt_key,
84e1051a39Sopenharmony_ci                       AES_encrypt, AES_decrypt, stream_enc, stream_dec);
85e1051a39Sopenharmony_ci    }
86e1051a39Sopenharmony_ci    return 1;
87e1051a39Sopenharmony_ci}
88e1051a39Sopenharmony_ci
89e1051a39Sopenharmony_cistatic void cipher_hw_aes_xts_copyctx(PROV_CIPHER_CTX *dst,
90e1051a39Sopenharmony_ci                                      const PROV_CIPHER_CTX *src)
91e1051a39Sopenharmony_ci{
92e1051a39Sopenharmony_ci    PROV_AES_XTS_CTX *sctx = (PROV_AES_XTS_CTX *)src;
93e1051a39Sopenharmony_ci    PROV_AES_XTS_CTX *dctx = (PROV_AES_XTS_CTX *)dst;
94e1051a39Sopenharmony_ci
95e1051a39Sopenharmony_ci    *dctx = *sctx;
96e1051a39Sopenharmony_ci    dctx->xts.key1 = &dctx->ks1.ks;
97e1051a39Sopenharmony_ci    dctx->xts.key2 = &dctx->ks2.ks;
98e1051a39Sopenharmony_ci}
99e1051a39Sopenharmony_ci
100e1051a39Sopenharmony_ci#if defined(AESNI_CAPABLE)
101e1051a39Sopenharmony_ci
102e1051a39Sopenharmony_cistatic int cipher_hw_aesni_xts_initkey(PROV_CIPHER_CTX *ctx,
103e1051a39Sopenharmony_ci                                       const unsigned char *key, size_t keylen)
104e1051a39Sopenharmony_ci{
105e1051a39Sopenharmony_ci    PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx;
106e1051a39Sopenharmony_ci
107e1051a39Sopenharmony_ci    XTS_SET_KEY_FN(aesni_set_encrypt_key, aesni_set_decrypt_key,
108e1051a39Sopenharmony_ci                   aesni_encrypt, aesni_decrypt,
109e1051a39Sopenharmony_ci                   aesni_xts_encrypt, aesni_xts_decrypt);
110e1051a39Sopenharmony_ci    return 1;
111e1051a39Sopenharmony_ci}
112e1051a39Sopenharmony_ci
113e1051a39Sopenharmony_ci# define PROV_CIPHER_HW_declare_xts()                                          \
114e1051a39Sopenharmony_cistatic const PROV_CIPHER_HW aesni_xts = {                                      \
115e1051a39Sopenharmony_ci    cipher_hw_aesni_xts_initkey,                                               \
116e1051a39Sopenharmony_ci    NULL,                                                                      \
117e1051a39Sopenharmony_ci    cipher_hw_aes_xts_copyctx                                                  \
118e1051a39Sopenharmony_ci};
119e1051a39Sopenharmony_ci# define PROV_CIPHER_HW_select_xts()                                           \
120e1051a39Sopenharmony_ciif (AESNI_CAPABLE)                                                             \
121e1051a39Sopenharmony_ci    return &aesni_xts;
122e1051a39Sopenharmony_ci
123e1051a39Sopenharmony_ci# elif defined(SPARC_AES_CAPABLE)
124e1051a39Sopenharmony_ci
125e1051a39Sopenharmony_cistatic int cipher_hw_aes_xts_t4_initkey(PROV_CIPHER_CTX *ctx,
126e1051a39Sopenharmony_ci                                        const unsigned char *key, size_t keylen)
127e1051a39Sopenharmony_ci{
128e1051a39Sopenharmony_ci    PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx;
129e1051a39Sopenharmony_ci    OSSL_xts_stream_fn stream_enc = NULL;
130e1051a39Sopenharmony_ci    OSSL_xts_stream_fn stream_dec = NULL;
131e1051a39Sopenharmony_ci
132e1051a39Sopenharmony_ci    /* Note: keylen is the size of 2 keys */
133e1051a39Sopenharmony_ci    switch (keylen) {
134e1051a39Sopenharmony_ci    case 32:
135e1051a39Sopenharmony_ci        stream_enc = aes128_t4_xts_encrypt;
136e1051a39Sopenharmony_ci        stream_dec = aes128_t4_xts_decrypt;
137e1051a39Sopenharmony_ci        break;
138e1051a39Sopenharmony_ci    case 64:
139e1051a39Sopenharmony_ci        stream_enc = aes256_t4_xts_encrypt;
140e1051a39Sopenharmony_ci        stream_dec = aes256_t4_xts_decrypt;
141e1051a39Sopenharmony_ci        break;
142e1051a39Sopenharmony_ci    default:
143e1051a39Sopenharmony_ci        return 0;
144e1051a39Sopenharmony_ci    }
145e1051a39Sopenharmony_ci
146e1051a39Sopenharmony_ci    XTS_SET_KEY_FN(aes_t4_set_encrypt_key, aes_t4_set_decrypt_key,
147e1051a39Sopenharmony_ci                   aes_t4_encrypt, aes_t4_decrypt,
148e1051a39Sopenharmony_ci                   stream_enc, stream_dec);
149e1051a39Sopenharmony_ci    return 1;
150e1051a39Sopenharmony_ci}
151e1051a39Sopenharmony_ci
152e1051a39Sopenharmony_ci# define PROV_CIPHER_HW_declare_xts()                                          \
153e1051a39Sopenharmony_cistatic const PROV_CIPHER_HW aes_xts_t4 = {                                     \
154e1051a39Sopenharmony_ci    cipher_hw_aes_xts_t4_initkey,                                              \
155e1051a39Sopenharmony_ci    NULL,                                                                      \
156e1051a39Sopenharmony_ci    cipher_hw_aes_xts_copyctx                                                  \
157e1051a39Sopenharmony_ci};
158e1051a39Sopenharmony_ci# define PROV_CIPHER_HW_select_xts()                                           \
159e1051a39Sopenharmony_ciif (SPARC_AES_CAPABLE)                                                         \
160e1051a39Sopenharmony_ci    return &aes_xts_t4;
161e1051a39Sopenharmony_ci# else
162e1051a39Sopenharmony_ci/* The generic case */
163e1051a39Sopenharmony_ci# define PROV_CIPHER_HW_declare_xts()
164e1051a39Sopenharmony_ci# define PROV_CIPHER_HW_select_xts()
165e1051a39Sopenharmony_ci#endif
166e1051a39Sopenharmony_ci
167e1051a39Sopenharmony_cistatic const PROV_CIPHER_HW aes_generic_xts = {
168e1051a39Sopenharmony_ci    cipher_hw_aes_xts_generic_initkey,
169e1051a39Sopenharmony_ci    NULL,
170e1051a39Sopenharmony_ci    cipher_hw_aes_xts_copyctx
171e1051a39Sopenharmony_ci};
172e1051a39Sopenharmony_ciPROV_CIPHER_HW_declare_xts()
173e1051a39Sopenharmony_ciconst PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_xts(size_t keybits)
174e1051a39Sopenharmony_ci{
175e1051a39Sopenharmony_ci    PROV_CIPHER_HW_select_xts()
176e1051a39Sopenharmony_ci    return &aes_generic_xts;
177e1051a39Sopenharmony_ci}
178