1f9429266SJens Wiklander // SPDX-License-Identifier: BSD-2-Clause
2f9429266SJens Wiklander /*
3f9429266SJens Wiklander * Copyright (c) 2015, Linaro Limited
4f9429266SJens Wiklander * All rights reserved.
5f9429266SJens Wiklander * Copyright (c) 2001-2007, Tom St Denis
6f9429266SJens Wiklander * All rights reserved.
7f9429266SJens Wiklander *
8f9429266SJens Wiklander * Redistribution and use in source and binary forms, with or without
9f9429266SJens Wiklander * modification, are permitted provided that the following conditions are met:
10f9429266SJens Wiklander *
11f9429266SJens Wiklander * 1. Redistributions of source code must retain the above copyright notice,
12f9429266SJens Wiklander * this list of conditions and the following disclaimer.
13f9429266SJens Wiklander *
14f9429266SJens Wiklander * 2. Redistributions in binary form must reproduce the above copyright notice,
15f9429266SJens Wiklander * this list of conditions and the following disclaimer in the documentation
16f9429266SJens Wiklander * and/or other materials provided with the distribution.
17f9429266SJens Wiklander *
18f9429266SJens Wiklander * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19f9429266SJens Wiklander * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20f9429266SJens Wiklander * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21f9429266SJens Wiklander * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22f9429266SJens Wiklander * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23f9429266SJens Wiklander * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24f9429266SJens Wiklander * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25f9429266SJens Wiklander * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26f9429266SJens Wiklander * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27f9429266SJens Wiklander * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28f9429266SJens Wiklander * POSSIBILITY OF SUCH DAMAGE.
29f9429266SJens Wiklander */
30f9429266SJens Wiklander
31f9429266SJens Wiklander /* LibTomCrypt, modular cryptographic library -- Tom St Denis
32f9429266SJens Wiklander *
33f9429266SJens Wiklander * LibTomCrypt is a library that provides various cryptographic
34f9429266SJens Wiklander * algorithms in a highly modular and flexible manner.
35f9429266SJens Wiklander *
36f9429266SJens Wiklander * The library is free for all purposes without any express
37f9429266SJens Wiklander * guarantee it works.
38f9429266SJens Wiklander *
39f9429266SJens Wiklander * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
40f9429266SJens Wiklander */
41f9429266SJens Wiklander
42f9429266SJens Wiklander /*
43f9429266SJens Wiklander * AES cipher for ARMv8 with Crypto Extensions
44f9429266SJens Wiklander *
45f9429266SJens Wiklander * Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
46f9429266SJens Wiklander */
47f9429266SJens Wiklander
48f9429266SJens Wiklander #include <compiler.h>
49f9429266SJens Wiklander #include <crypto/crypto_accel.h>
50f9429266SJens Wiklander #include <tomcrypt_private.h>
51f9429266SJens Wiklander
522a65ecafSJens Wiklander #define EXPANDED_AES_KEY_WORD_COUNT 60
532a65ecafSJens Wiklander #define EXPANDED_AES_KEY_LEN (EXPANDED_AES_KEY_WORD_COUNT * \
542a65ecafSJens Wiklander sizeof(uint32_t))
552a65ecafSJens Wiklander
rijndael_setup(const unsigned char * key,int keylen,int num_rounds,symmetric_key * skey)56f9429266SJens Wiklander int rijndael_setup(const unsigned char *key, int keylen, int num_rounds,
57f9429266SJens Wiklander symmetric_key *skey)
58f9429266SJens Wiklander {
59f9429266SJens Wiklander unsigned int round_count = 0;
60f9429266SJens Wiklander
61f9429266SJens Wiklander LTC_ARGCHK(key);
62f9429266SJens Wiklander LTC_ARGCHK(skey);
63f9429266SJens Wiklander
64f9429266SJens Wiklander if (keylen != 16 && keylen != 24 && keylen != 32)
65f9429266SJens Wiklander return CRYPT_INVALID_KEYSIZE;
66f9429266SJens Wiklander
672a65ecafSJens Wiklander skey->rijndael.eK = LTC_ALIGN_BUF(skey->rijndael.K, 16);
682a65ecafSJens Wiklander skey->rijndael.dK = skey->rijndael.eK + EXPANDED_AES_KEY_WORD_COUNT;
692a65ecafSJens Wiklander
70f9429266SJens Wiklander if (crypto_accel_aes_expand_keys(key, keylen, skey->rijndael.eK,
71f9429266SJens Wiklander skey->rijndael.dK,
722a65ecafSJens Wiklander EXPANDED_AES_KEY_LEN,
73f9429266SJens Wiklander &round_count))
74f9429266SJens Wiklander return CRYPT_INVALID_ARG;
75f9429266SJens Wiklander
76f9429266SJens Wiklander if (num_rounds && (unsigned int)num_rounds != round_count)
77f9429266SJens Wiklander return CRYPT_INVALID_ROUNDS;
78f9429266SJens Wiklander
79f9429266SJens Wiklander skey->rijndael.Nr = round_count;
80f9429266SJens Wiklander
81f9429266SJens Wiklander return CRYPT_OK;
82f9429266SJens Wiklander }
83f9429266SJens Wiklander
rijndael_done(symmetric_key * skey __unused)84f9429266SJens Wiklander void rijndael_done(symmetric_key *skey __unused)
85f9429266SJens Wiklander {
86f9429266SJens Wiklander }
87f9429266SJens Wiklander
rijndael_keysize(int * keysize)88f9429266SJens Wiklander int rijndael_keysize(int *keysize)
89f9429266SJens Wiklander {
90f9429266SJens Wiklander LTC_ARGCHK(keysize);
91f9429266SJens Wiklander
92f9429266SJens Wiklander if (*keysize < 16)
93f9429266SJens Wiklander return CRYPT_INVALID_KEYSIZE;
94f9429266SJens Wiklander else if (*keysize < 24)
95f9429266SJens Wiklander *keysize = 16;
96f9429266SJens Wiklander else if (*keysize < 32)
97f9429266SJens Wiklander *keysize = 24;
98f9429266SJens Wiklander else
99f9429266SJens Wiklander *keysize = 32;
100f9429266SJens Wiklander
101f9429266SJens Wiklander return CRYPT_OK;
102f9429266SJens Wiklander }
103f9429266SJens Wiklander
aes_ecb_encrypt_nblocks(const unsigned char * pt,unsigned char * ct,unsigned long blocks,const symmetric_key * skey)104f9429266SJens Wiklander static int aes_ecb_encrypt_nblocks(const unsigned char *pt, unsigned char *ct,
105f9429266SJens Wiklander unsigned long blocks,
106f9429266SJens Wiklander const symmetric_key *skey)
107f9429266SJens Wiklander {
108f9429266SJens Wiklander LTC_ARGCHK(pt);
109f9429266SJens Wiklander LTC_ARGCHK(ct);
110f9429266SJens Wiklander LTC_ARGCHK(skey);
111f9429266SJens Wiklander
112f9429266SJens Wiklander crypto_accel_aes_ecb_enc(ct, pt, skey->rijndael.eK, skey->rijndael.Nr,
113f9429266SJens Wiklander blocks);
114f9429266SJens Wiklander return CRYPT_OK;
115f9429266SJens Wiklander }
116f9429266SJens Wiklander
aes_ecb_decrypt_nblocks(const unsigned char * ct,unsigned char * pt,unsigned long blocks,const symmetric_key * skey)117f9429266SJens Wiklander static int aes_ecb_decrypt_nblocks(const unsigned char *ct, unsigned char *pt,
118f9429266SJens Wiklander unsigned long blocks,
119f9429266SJens Wiklander const symmetric_key *skey)
120f9429266SJens Wiklander {
121f9429266SJens Wiklander LTC_ARGCHK(pt);
122f9429266SJens Wiklander LTC_ARGCHK(ct);
123f9429266SJens Wiklander LTC_ARGCHK(skey);
124f9429266SJens Wiklander
125f9429266SJens Wiklander crypto_accel_aes_ecb_dec(pt, ct, skey->rijndael.dK, skey->rijndael.Nr,
126f9429266SJens Wiklander blocks);
127f9429266SJens Wiklander
128f9429266SJens Wiklander return CRYPT_OK;
129f9429266SJens Wiklander }
130f9429266SJens Wiklander
rijndael_ecb_encrypt(const unsigned char * pt,unsigned char * ct,const symmetric_key * skey)131f9429266SJens Wiklander int rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct,
132f9429266SJens Wiklander const symmetric_key *skey)
133f9429266SJens Wiklander {
134f9429266SJens Wiklander return aes_ecb_encrypt_nblocks(pt, ct, 1, skey);
135f9429266SJens Wiklander }
136f9429266SJens Wiklander
rijndael_ecb_decrypt(const unsigned char * ct,unsigned char * pt,const symmetric_key * skey)137f9429266SJens Wiklander int rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt,
138f9429266SJens Wiklander const symmetric_key *skey)
139f9429266SJens Wiklander {
140f9429266SJens Wiklander return aes_ecb_decrypt_nblocks(ct, pt, 1, skey);
141f9429266SJens Wiklander }
142f9429266SJens Wiklander
aes_cbc_encrypt_nblocks(const unsigned char * pt,unsigned char * ct,unsigned long blocks,unsigned char * IV,symmetric_key * skey)143f9429266SJens Wiklander static int aes_cbc_encrypt_nblocks(const unsigned char *pt, unsigned char *ct,
144f9429266SJens Wiklander unsigned long blocks, unsigned char *IV,
145f9429266SJens Wiklander symmetric_key *skey)
146f9429266SJens Wiklander {
147f9429266SJens Wiklander LTC_ARGCHK(pt);
148f9429266SJens Wiklander LTC_ARGCHK(ct);
149f9429266SJens Wiklander LTC_ARGCHK(IV);
150f9429266SJens Wiklander LTC_ARGCHK(skey);
151f9429266SJens Wiklander
152f9429266SJens Wiklander crypto_accel_aes_cbc_enc(ct, pt, skey->rijndael.eK, skey->rijndael.Nr,
153f9429266SJens Wiklander blocks, IV);
154f9429266SJens Wiklander
155f9429266SJens Wiklander return CRYPT_OK;
156f9429266SJens Wiklander }
157f9429266SJens Wiklander
aes_cbc_decrypt_nblocks(const unsigned char * ct,unsigned char * pt,unsigned long blocks,unsigned char * IV,symmetric_key * skey)158f9429266SJens Wiklander static int aes_cbc_decrypt_nblocks(const unsigned char *ct, unsigned char *pt,
159f9429266SJens Wiklander unsigned long blocks, unsigned char *IV,
160f9429266SJens Wiklander symmetric_key *skey)
161f9429266SJens Wiklander {
162f9429266SJens Wiklander LTC_ARGCHK(pt);
163f9429266SJens Wiklander LTC_ARGCHK(ct);
164f9429266SJens Wiklander LTC_ARGCHK(IV);
165f9429266SJens Wiklander LTC_ARGCHK(skey);
166f9429266SJens Wiklander
167f9429266SJens Wiklander crypto_accel_aes_cbc_dec(pt, ct, skey->rijndael.dK, skey->rijndael.Nr,
168f9429266SJens Wiklander blocks, IV);
169f9429266SJens Wiklander
170f9429266SJens Wiklander return CRYPT_OK;
171f9429266SJens Wiklander }
172f9429266SJens Wiklander
173*f6be0e13SJacob Kroon #ifdef LTC_CTR_MODE
aes_ctr_encrypt_nblocks(const unsigned char * pt,unsigned char * ct,unsigned long blocks,unsigned char * IV,int mode,symmetric_key * skey)174f9429266SJens Wiklander static int aes_ctr_encrypt_nblocks(const unsigned char *pt, unsigned char *ct,
175f9429266SJens Wiklander unsigned long blocks, unsigned char *IV,
176f9429266SJens Wiklander int mode, symmetric_key *skey)
177f9429266SJens Wiklander {
178f9429266SJens Wiklander LTC_ARGCHK(pt);
179f9429266SJens Wiklander LTC_ARGCHK(ct);
180f9429266SJens Wiklander LTC_ARGCHK(IV);
181f9429266SJens Wiklander LTC_ARGCHK(skey);
182f9429266SJens Wiklander
183f9429266SJens Wiklander if (mode == CTR_COUNTER_LITTLE_ENDIAN) {
184f9429266SJens Wiklander /* Accelerated algorithm supports big endian only */
185f9429266SJens Wiklander return CRYPT_ERROR;
186f9429266SJens Wiklander }
187f9429266SJens Wiklander
188f9429266SJens Wiklander crypto_accel_aes_ctr_be_enc(ct, pt, skey->rijndael.eK,
189f9429266SJens Wiklander skey->rijndael.Nr, blocks, IV);
190f9429266SJens Wiklander
191f9429266SJens Wiklander return CRYPT_OK;
192f9429266SJens Wiklander }
193*f6be0e13SJacob Kroon #endif
194f9429266SJens Wiklander
aes_xts_encrypt_nblocks(const unsigned char * pt,unsigned char * ct,unsigned long blocks,unsigned char * tweak,const symmetric_key * skey1,const symmetric_key * skey2)195f9429266SJens Wiklander static int aes_xts_encrypt_nblocks(const unsigned char *pt, unsigned char *ct,
196f9429266SJens Wiklander unsigned long blocks, unsigned char *tweak,
197f9429266SJens Wiklander const symmetric_key *skey1,
198f9429266SJens Wiklander const symmetric_key *skey2)
199f9429266SJens Wiklander {
200f9429266SJens Wiklander LTC_ARGCHK(pt);
201f9429266SJens Wiklander LTC_ARGCHK(ct);
202f9429266SJens Wiklander LTC_ARGCHK(tweak);
203f9429266SJens Wiklander LTC_ARGCHK(skey1);
204f9429266SJens Wiklander LTC_ARGCHK(skey2);
205f9429266SJens Wiklander LTC_ARGCHK(skey1->rijndael.Nr == skey2->rijndael.Nr);
206f9429266SJens Wiklander
207f9429266SJens Wiklander
208f9429266SJens Wiklander crypto_accel_aes_xts_enc(ct, pt, skey1->rijndael.eK,
209f9429266SJens Wiklander skey1->rijndael.Nr, blocks,
210f9429266SJens Wiklander skey2->rijndael.eK, tweak);
211f9429266SJens Wiklander
212f9429266SJens Wiklander return CRYPT_OK;
213f9429266SJens Wiklander }
214f9429266SJens Wiklander
aes_xts_decrypt_nblocks(const unsigned char * ct,unsigned char * pt,unsigned long blocks,unsigned char * tweak,const symmetric_key * skey1,const symmetric_key * skey2)215f9429266SJens Wiklander static int aes_xts_decrypt_nblocks(const unsigned char *ct, unsigned char *pt,
216f9429266SJens Wiklander unsigned long blocks, unsigned char *tweak,
217f9429266SJens Wiklander const symmetric_key *skey1,
218f9429266SJens Wiklander const symmetric_key *skey2)
219f9429266SJens Wiklander {
220f9429266SJens Wiklander LTC_ARGCHK(pt);
221f9429266SJens Wiklander LTC_ARGCHK(ct);
222f9429266SJens Wiklander LTC_ARGCHK(tweak);
223f9429266SJens Wiklander LTC_ARGCHK(skey1);
224f9429266SJens Wiklander LTC_ARGCHK(skey2);
225f9429266SJens Wiklander LTC_ARGCHK(skey1->rijndael.Nr == skey2->rijndael.Nr);
226f9429266SJens Wiklander
227f9429266SJens Wiklander crypto_accel_aes_xts_dec(pt, ct, skey1->rijndael.dK,
228f9429266SJens Wiklander skey1->rijndael.Nr, blocks,
229f9429266SJens Wiklander skey2->rijndael.eK, tweak);
230f9429266SJens Wiklander
231f9429266SJens Wiklander return CRYPT_OK;
232f9429266SJens Wiklander }
233f9429266SJens Wiklander
234f9429266SJens Wiklander const struct ltc_cipher_descriptor aes_desc = {
235f9429266SJens Wiklander .name = "aes",
236f9429266SJens Wiklander .ID = 6,
237f9429266SJens Wiklander .min_key_length = 16,
238f9429266SJens Wiklander .max_key_length = 32,
239f9429266SJens Wiklander .block_length = 16,
240f9429266SJens Wiklander .default_rounds = 10,
241f9429266SJens Wiklander .setup = rijndael_setup,
242f9429266SJens Wiklander .ecb_encrypt = rijndael_ecb_encrypt,
243f9429266SJens Wiklander .ecb_decrypt = rijndael_ecb_decrypt,
244f9429266SJens Wiklander .done = rijndael_done,
245f9429266SJens Wiklander .keysize = rijndael_keysize,
246f9429266SJens Wiklander .accel_ecb_encrypt = aes_ecb_encrypt_nblocks,
247f9429266SJens Wiklander .accel_ecb_decrypt = aes_ecb_decrypt_nblocks,
248f9429266SJens Wiklander .accel_cbc_encrypt = aes_cbc_encrypt_nblocks,
249f9429266SJens Wiklander .accel_cbc_decrypt = aes_cbc_decrypt_nblocks,
250*f6be0e13SJacob Kroon #ifdef LTC_CTR_MODE
251f9429266SJens Wiklander .accel_ctr_encrypt = aes_ctr_encrypt_nblocks,
252*f6be0e13SJacob Kroon #endif
253f9429266SJens Wiklander .accel_xts_encrypt = aes_xts_encrypt_nblocks,
254f9429266SJens Wiklander .accel_xts_decrypt = aes_xts_decrypt_nblocks,
255f9429266SJens Wiklander };
256