1*44f8e1e8SMark Johnston /*-
2*44f8e1e8SMark Johnston * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3*44f8e1e8SMark Johnston *
4*44f8e1e8SMark Johnston * Copyright (c) 2023 Stormshield
5*44f8e1e8SMark Johnston * Copyright (c) 2023 Semihalf
6*44f8e1e8SMark Johnston *
7*44f8e1e8SMark Johnston * Redistribution and use in source and binary forms, with or without
8*44f8e1e8SMark Johnston * modification, are permitted provided that the following conditions
9*44f8e1e8SMark Johnston * are met:
10*44f8e1e8SMark Johnston * 1. Redistributions of source code must retain the above copyright
11*44f8e1e8SMark Johnston * notice, this list of conditions and the following disclaimer,
12*44f8e1e8SMark Johnston * without modification.
13*44f8e1e8SMark Johnston * 2. Redistributions in binary form must reproduce at minimum a disclaimer
14*44f8e1e8SMark Johnston * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
15*44f8e1e8SMark Johnston * redistribution must be conditioned upon including a substantially
16*44f8e1e8SMark Johnston * similar Disclaimer requirement for further binary redistribution.
17*44f8e1e8SMark Johnston *
18*44f8e1e8SMark Johnston * NO WARRANTY
19*44f8e1e8SMark Johnston * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20*44f8e1e8SMark Johnston * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21*44f8e1e8SMark Johnston * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
22*44f8e1e8SMark Johnston * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
23*44f8e1e8SMark Johnston * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
24*44f8e1e8SMark Johnston * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*44f8e1e8SMark Johnston * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*44f8e1e8SMark Johnston * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
27*44f8e1e8SMark Johnston * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*44f8e1e8SMark Johnston * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
29*44f8e1e8SMark Johnston * THE POSSIBILITY OF SUCH DAMAGES.
30*44f8e1e8SMark Johnston */
31*44f8e1e8SMark Johnston
32*44f8e1e8SMark Johnston #ifndef __OSSL_ARM__
33*44f8e1e8SMark Johnston #define __OSSL_ARM__
34*44f8e1e8SMark Johnston
35*44f8e1e8SMark Johnston #include <crypto/openssl/ossl.h>
36*44f8e1e8SMark Johnston #include <crypto/openssl/ossl_cipher.h>
37*44f8e1e8SMark Johnston
38*44f8e1e8SMark Johnston #include <opencrypto/cryptodev.h>
39*44f8e1e8SMark Johnston
40*44f8e1e8SMark Johnston struct bsaes_key {
41*44f8e1e8SMark Johnston struct ossl_aes_keysched ks;
42*44f8e1e8SMark Johnston int converted;
43*44f8e1e8SMark Johnston #define BSAES_KEY_SIZE (128 * (RIJNDAEL_MAXNR - 1) + 2 * AES_BLOCK_LEN)
44*44f8e1e8SMark Johnston uint8_t bitslice[BSAES_KEY_SIZE] __aligned(8);
45*44f8e1e8SMark Johnston } __aligned(8);
46*44f8e1e8SMark Johnston
47*44f8e1e8SMark Johnston ossl_cipher_encrypt_t ossl_bsaes_cbc_encrypt;
48*44f8e1e8SMark Johnston
49*44f8e1e8SMark Johnston void AES_encrypt(const void *, void *, const void *);
50*44f8e1e8SMark Johnston
51*44f8e1e8SMark Johnston static inline void
AES_CBC_ENCRYPT(const unsigned char * in,unsigned char * out,size_t length,const void * key,unsigned char * iv,int encrypt)52*44f8e1e8SMark Johnston AES_CBC_ENCRYPT(const unsigned char *in, unsigned char *out,
53*44f8e1e8SMark Johnston size_t length, const void *key, unsigned char *iv, int encrypt)
54*44f8e1e8SMark Johnston {
55*44f8e1e8SMark Johnston struct bsaes_key bsks;
56*44f8e1e8SMark Johnston uint32_t iv32[4], scratch[4];
57*44f8e1e8SMark Johnston
58*44f8e1e8SMark Johnston /*
59*44f8e1e8SMark Johnston * bsaes_cbc_encrypt has some special requirements w.r.t input data.
60*44f8e1e8SMark Johnston * The key buffer, that normally holds round keys is used as a scratch
61*44f8e1e8SMark Johnston * space. 128 bytes per round of extra space is required.
62*44f8e1e8SMark Johnston * Another thing is that only decryption is supported.
63*44f8e1e8SMark Johnston * In the case of encryption block chaining has to be done in C.
64*44f8e1e8SMark Johnston */
65*44f8e1e8SMark Johnston if (!encrypt) {
66*44f8e1e8SMark Johnston memcpy(&bsks.ks, key, sizeof(bsks.ks));
67*44f8e1e8SMark Johnston bsks.converted = 0;
68*44f8e1e8SMark Johnston ossl_bsaes_cbc_encrypt(in, out, length, &bsks, iv, false);
69*44f8e1e8SMark Johnston return;
70*44f8e1e8SMark Johnston }
71*44f8e1e8SMark Johnston
72*44f8e1e8SMark Johnston length /= AES_BLOCK_LEN;
73*44f8e1e8SMark Johnston memcpy(iv32, iv, AES_BLOCK_LEN);
74*44f8e1e8SMark Johnston
75*44f8e1e8SMark Johnston while (length-- > 0) {
76*44f8e1e8SMark Johnston memcpy(scratch, in, AES_BLOCK_LEN);
77*44f8e1e8SMark Johnston
78*44f8e1e8SMark Johnston /* XOR plaintext with IV. */
79*44f8e1e8SMark Johnston scratch[0] ^= iv32[0];
80*44f8e1e8SMark Johnston scratch[1] ^= iv32[1];
81*44f8e1e8SMark Johnston scratch[2] ^= iv32[2];
82*44f8e1e8SMark Johnston scratch[3] ^= iv32[3];
83*44f8e1e8SMark Johnston
84*44f8e1e8SMark Johnston AES_encrypt(scratch, out, key);
85*44f8e1e8SMark Johnston
86*44f8e1e8SMark Johnston memcpy(iv32, out, AES_BLOCK_LEN);
87*44f8e1e8SMark Johnston in += AES_BLOCK_LEN;
88*44f8e1e8SMark Johnston out += AES_BLOCK_LEN;
89*44f8e1e8SMark Johnston }
90*44f8e1e8SMark Johnston
91*44f8e1e8SMark Johnston memcpy(iv, iv32, AES_BLOCK_LEN);
92*44f8e1e8SMark Johnston }
93*44f8e1e8SMark Johnston
94*44f8e1e8SMark Johnston #endif /* __OSSL_ARM__ */
95