]>
Commit | Line | Data |
---|---|---|
16609980 GBY |
1 | /* |
2 | * Copyright (C) 2012-2017 ARM Limited or its affiliates. | |
c8f17865 | 3 | * |
16609980 GBY |
4 | * This program is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License version 2 as | |
6 | * published by the Free Software Foundation. | |
c8f17865 | 7 | * |
16609980 GBY |
8 | * This program is distributed in the hope that it will be useful, |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | * GNU General Public License for more details. | |
c8f17865 | 12 | * |
16609980 GBY |
13 | * You should have received a copy of the GNU General Public License |
14 | * along with this program; if not, see <http://www.gnu.org/licenses/>. | |
15 | */ | |
16 | ||
17 | /************************************************************** | |
161d6dd8 DR |
18 | * This file defines the driver FIPS Low Level implmentaion functions, |
19 | * that executes the KAT. | |
20 | ***************************************************************/ | |
16609980 GBY |
21 | #include <linux/kernel.h> |
22 | ||
23 | #include "ssi_driver.h" | |
24 | #include "ssi_fips_local.h" | |
25 | #include "ssi_fips_data.h" | |
26 | #include "cc_crypto_ctx.h" | |
27 | #include "ssi_hash.h" | |
28 | #include "ssi_request_mgr.h" | |
29 | ||
30 | ||
a1ab41eb | 31 | static const u32 digest_len_init[] = { |
16609980 | 32 | 0x00000040, 0x00000000, 0x00000000, 0x00000000 }; |
a1ab41eb | 33 | static const u32 sha1_init[] = { |
16609980 | 34 | SHA1_H4, SHA1_H3, SHA1_H2, SHA1_H1, SHA1_H0 }; |
a1ab41eb | 35 | static const u32 sha256_init[] = { |
16609980 GBY |
36 | SHA256_H7, SHA256_H6, SHA256_H5, SHA256_H4, |
37 | SHA256_H3, SHA256_H2, SHA256_H1, SHA256_H0 }; | |
38 | #if (CC_SUPPORT_SHA > 256) | |
a1ab41eb | 39 | static const u32 digest_len_sha512_init[] = { |
16609980 | 40 | 0x00000080, 0x00000000, 0x00000000, 0x00000000 }; |
a1ab41eb | 41 | static const u64 sha512_init[] = { |
16609980 GBY |
42 | SHA512_H7, SHA512_H6, SHA512_H5, SHA512_H4, |
43 | SHA512_H3, SHA512_H2, SHA512_H1, SHA512_H0 }; | |
44 | #endif | |
45 | ||
46 | ||
47 | #define NIST_CIPHER_AES_MAX_VECTOR_SIZE 32 | |
48 | ||
49 | struct fips_cipher_ctx { | |
a1ab41eb GBY |
50 | u8 iv[CC_AES_IV_SIZE]; |
51 | u8 key[AES_512_BIT_KEY_SIZE]; | |
52 | u8 din[NIST_CIPHER_AES_MAX_VECTOR_SIZE]; | |
53 | u8 dout[NIST_CIPHER_AES_MAX_VECTOR_SIZE]; | |
16609980 GBY |
54 | }; |
55 | ||
56 | typedef struct _FipsCipherData { | |
a1ab41eb GBY |
57 | u8 isAes; |
58 | u8 key[AES_512_BIT_KEY_SIZE]; | |
16609980 | 59 | size_t keySize; |
a1ab41eb | 60 | u8 iv[CC_AES_IV_SIZE]; |
16609980 GBY |
61 | enum drv_crypto_direction direction; |
62 | enum drv_cipher_mode oprMode; | |
a1ab41eb GBY |
63 | u8 dataIn[NIST_CIPHER_AES_MAX_VECTOR_SIZE]; |
64 | u8 dataOut[NIST_CIPHER_AES_MAX_VECTOR_SIZE]; | |
16609980 GBY |
65 | size_t dataInSize; |
66 | } FipsCipherData; | |
67 | ||
68 | ||
69 | struct fips_cmac_ctx { | |
a1ab41eb GBY |
70 | u8 key[AES_256_BIT_KEY_SIZE]; |
71 | u8 din[NIST_CIPHER_AES_MAX_VECTOR_SIZE]; | |
72 | u8 mac_res[CC_DIGEST_SIZE_MAX]; | |
16609980 GBY |
73 | }; |
74 | ||
75 | typedef struct _FipsCmacData { | |
76 | enum drv_crypto_direction direction; | |
a1ab41eb | 77 | u8 key[AES_256_BIT_KEY_SIZE]; |
16609980 | 78 | size_t key_size; |
a1ab41eb | 79 | u8 data_in[NIST_CIPHER_AES_MAX_VECTOR_SIZE]; |
16609980 | 80 | size_t data_in_size; |
a1ab41eb | 81 | u8 mac_res[CC_DIGEST_SIZE_MAX]; |
16609980 GBY |
82 | size_t mac_res_size; |
83 | } FipsCmacData; | |
84 | ||
85 | ||
86 | struct fips_hash_ctx { | |
a1ab41eb GBY |
87 | u8 initial_digest[CC_DIGEST_SIZE_MAX]; |
88 | u8 din[NIST_SHA_MSG_SIZE]; | |
89 | u8 mac_res[CC_DIGEST_SIZE_MAX]; | |
16609980 GBY |
90 | }; |
91 | ||
92 | typedef struct _FipsHashData { | |
93 | enum drv_hash_mode hash_mode; | |
a1ab41eb | 94 | u8 data_in[NIST_SHA_MSG_SIZE]; |
16609980 | 95 | size_t data_in_size; |
a1ab41eb | 96 | u8 mac_res[CC_DIGEST_SIZE_MAX]; |
16609980 GBY |
97 | } FipsHashData; |
98 | ||
99 | ||
100 | /* note that the hmac key length must be equal or less than block size (block size is 64 up to sha256 and 128 for sha384/512) */ | |
101 | struct fips_hmac_ctx { | |
a1ab41eb GBY |
102 | u8 initial_digest[CC_DIGEST_SIZE_MAX]; |
103 | u8 key[CC_HMAC_BLOCK_SIZE_MAX]; | |
104 | u8 k0[CC_HMAC_BLOCK_SIZE_MAX]; | |
105 | u8 digest_bytes_len[HASH_LEN_SIZE]; | |
106 | u8 tmp_digest[CC_DIGEST_SIZE_MAX]; | |
107 | u8 din[NIST_HMAC_MSG_SIZE]; | |
108 | u8 mac_res[CC_DIGEST_SIZE_MAX]; | |
16609980 GBY |
109 | }; |
110 | ||
111 | typedef struct _FipsHmacData { | |
112 | enum drv_hash_mode hash_mode; | |
a1ab41eb | 113 | u8 key[CC_HMAC_BLOCK_SIZE_MAX]; |
16609980 | 114 | size_t key_size; |
a1ab41eb | 115 | u8 data_in[NIST_HMAC_MSG_SIZE]; |
16609980 | 116 | size_t data_in_size; |
a1ab41eb | 117 | u8 mac_res[CC_DIGEST_SIZE_MAX]; |
16609980 GBY |
118 | } FipsHmacData; |
119 | ||
120 | ||
121 | #define FIPS_CCM_B0_A0_ADATA_SIZE (NIST_AESCCM_IV_SIZE + NIST_AESCCM_IV_SIZE + NIST_AESCCM_ADATA_SIZE) | |
122 | ||
123 | struct fips_ccm_ctx { | |
a1ab41eb GBY |
124 | u8 b0_a0_adata[FIPS_CCM_B0_A0_ADATA_SIZE]; |
125 | u8 iv[NIST_AESCCM_IV_SIZE]; | |
126 | u8 ctr_cnt_0[NIST_AESCCM_IV_SIZE]; | |
127 | u8 key[CC_AES_KEY_SIZE_MAX]; | |
128 | u8 din[NIST_AESCCM_TEXT_SIZE]; | |
129 | u8 dout[NIST_AESCCM_TEXT_SIZE]; | |
130 | u8 mac_res[NIST_AESCCM_TAG_SIZE]; | |
16609980 GBY |
131 | }; |
132 | ||
133 | typedef struct _FipsCcmData { | |
134 | enum drv_crypto_direction direction; | |
a1ab41eb | 135 | u8 key[CC_AES_KEY_SIZE_MAX]; |
16609980 | 136 | size_t keySize; |
a1ab41eb GBY |
137 | u8 nonce[NIST_AESCCM_NONCE_SIZE]; |
138 | u8 adata[NIST_AESCCM_ADATA_SIZE]; | |
16609980 | 139 | size_t adataSize; |
a1ab41eb | 140 | u8 dataIn[NIST_AESCCM_TEXT_SIZE]; |
16609980 | 141 | size_t dataInSize; |
a1ab41eb GBY |
142 | u8 dataOut[NIST_AESCCM_TEXT_SIZE]; |
143 | u8 tagSize; | |
144 | u8 macResOut[NIST_AESCCM_TAG_SIZE]; | |
16609980 GBY |
145 | } FipsCcmData; |
146 | ||
147 | ||
148 | struct fips_gcm_ctx { | |
a1ab41eb GBY |
149 | u8 adata[NIST_AESGCM_ADATA_SIZE]; |
150 | u8 key[CC_AES_KEY_SIZE_MAX]; | |
151 | u8 hkey[CC_AES_KEY_SIZE_MAX]; | |
152 | u8 din[NIST_AESGCM_TEXT_SIZE]; | |
153 | u8 dout[NIST_AESGCM_TEXT_SIZE]; | |
154 | u8 mac_res[NIST_AESGCM_TAG_SIZE]; | |
155 | u8 len_block[AES_BLOCK_SIZE]; | |
156 | u8 iv_inc1[AES_BLOCK_SIZE]; | |
157 | u8 iv_inc2[AES_BLOCK_SIZE]; | |
16609980 GBY |
158 | }; |
159 | ||
160 | typedef struct _FipsGcmData { | |
161 | enum drv_crypto_direction direction; | |
a1ab41eb | 162 | u8 key[CC_AES_KEY_SIZE_MAX]; |
16609980 | 163 | size_t keySize; |
a1ab41eb GBY |
164 | u8 iv[NIST_AESGCM_IV_SIZE]; |
165 | u8 adata[NIST_AESGCM_ADATA_SIZE]; | |
16609980 | 166 | size_t adataSize; |
a1ab41eb | 167 | u8 dataIn[NIST_AESGCM_TEXT_SIZE]; |
16609980 | 168 | size_t dataInSize; |
a1ab41eb GBY |
169 | u8 dataOut[NIST_AESGCM_TEXT_SIZE]; |
170 | u8 tagSize; | |
171 | u8 macResOut[NIST_AESGCM_TAG_SIZE]; | |
16609980 GBY |
172 | } FipsGcmData; |
173 | ||
174 | ||
175 | typedef union _fips_ctx { | |
176 | struct fips_cipher_ctx cipher; | |
177 | struct fips_cmac_ctx cmac; | |
178 | struct fips_hash_ctx hash; | |
179 | struct fips_hmac_ctx hmac; | |
180 | struct fips_ccm_ctx ccm; | |
181 | struct fips_gcm_ctx gcm; | |
182 | } fips_ctx; | |
183 | ||
184 | ||
185 | /* test data tables */ | |
186 | static const FipsCipherData FipsCipherDataTable[] = { | |
187 | /* AES */ | |
188 | { 1, NIST_AES_128_KEY, CC_AES_128_BIT_KEY_SIZE, NIST_AES_ECB_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_ECB, NIST_AES_PLAIN_DATA, NIST_AES_128_ECB_CIPHER, NIST_AES_VECTOR_SIZE }, | |
189 | { 1, NIST_AES_128_KEY, CC_AES_128_BIT_KEY_SIZE, NIST_AES_ECB_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_ECB, NIST_AES_128_ECB_CIPHER, NIST_AES_PLAIN_DATA, NIST_AES_VECTOR_SIZE }, | |
190 | { 1, NIST_AES_192_KEY, CC_AES_192_BIT_KEY_SIZE, NIST_AES_ECB_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_ECB, NIST_AES_PLAIN_DATA, NIST_AES_192_ECB_CIPHER, NIST_AES_VECTOR_SIZE }, | |
191 | { 1, NIST_AES_192_KEY, CC_AES_192_BIT_KEY_SIZE, NIST_AES_ECB_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_ECB, NIST_AES_192_ECB_CIPHER, NIST_AES_PLAIN_DATA, NIST_AES_VECTOR_SIZE }, | |
192 | { 1, NIST_AES_256_KEY, CC_AES_256_BIT_KEY_SIZE, NIST_AES_ECB_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_ECB, NIST_AES_PLAIN_DATA, NIST_AES_256_ECB_CIPHER, NIST_AES_VECTOR_SIZE }, | |
193 | { 1, NIST_AES_256_KEY, CC_AES_256_BIT_KEY_SIZE, NIST_AES_ECB_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_ECB, NIST_AES_256_ECB_CIPHER, NIST_AES_PLAIN_DATA, NIST_AES_VECTOR_SIZE }, | |
194 | { 1, NIST_AES_128_KEY, CC_AES_128_BIT_KEY_SIZE, NIST_AES_CBC_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_CBC, NIST_AES_PLAIN_DATA, NIST_AES_128_CBC_CIPHER, NIST_AES_VECTOR_SIZE }, | |
195 | { 1, NIST_AES_128_KEY, CC_AES_128_BIT_KEY_SIZE, NIST_AES_CBC_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_CBC, NIST_AES_128_CBC_CIPHER, NIST_AES_PLAIN_DATA, NIST_AES_VECTOR_SIZE }, | |
196 | { 1, NIST_AES_192_KEY, CC_AES_192_BIT_KEY_SIZE, NIST_AES_CBC_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_CBC, NIST_AES_PLAIN_DATA, NIST_AES_192_CBC_CIPHER, NIST_AES_VECTOR_SIZE }, | |
197 | { 1, NIST_AES_192_KEY, CC_AES_192_BIT_KEY_SIZE, NIST_AES_CBC_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_CBC, NIST_AES_192_CBC_CIPHER, NIST_AES_PLAIN_DATA, NIST_AES_VECTOR_SIZE }, | |
198 | { 1, NIST_AES_256_KEY, CC_AES_256_BIT_KEY_SIZE, NIST_AES_CBC_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_CBC, NIST_AES_PLAIN_DATA, NIST_AES_256_CBC_CIPHER, NIST_AES_VECTOR_SIZE }, | |
199 | { 1, NIST_AES_256_KEY, CC_AES_256_BIT_KEY_SIZE, NIST_AES_CBC_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_CBC, NIST_AES_256_CBC_CIPHER, NIST_AES_PLAIN_DATA, NIST_AES_VECTOR_SIZE }, | |
200 | { 1, NIST_AES_128_KEY, CC_AES_128_BIT_KEY_SIZE, NIST_AES_OFB_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_OFB, NIST_AES_PLAIN_DATA, NIST_AES_128_OFB_CIPHER, NIST_AES_VECTOR_SIZE }, | |
201 | { 1, NIST_AES_128_KEY, CC_AES_128_BIT_KEY_SIZE, NIST_AES_OFB_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_OFB, NIST_AES_128_OFB_CIPHER, NIST_AES_PLAIN_DATA, NIST_AES_VECTOR_SIZE }, | |
202 | { 1, NIST_AES_192_KEY, CC_AES_192_BIT_KEY_SIZE, NIST_AES_OFB_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_OFB, NIST_AES_PLAIN_DATA, NIST_AES_192_OFB_CIPHER, NIST_AES_VECTOR_SIZE }, | |
203 | { 1, NIST_AES_192_KEY, CC_AES_192_BIT_KEY_SIZE, NIST_AES_OFB_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_OFB, NIST_AES_192_OFB_CIPHER, NIST_AES_PLAIN_DATA, NIST_AES_VECTOR_SIZE }, | |
204 | { 1, NIST_AES_256_KEY, CC_AES_256_BIT_KEY_SIZE, NIST_AES_OFB_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_OFB, NIST_AES_PLAIN_DATA, NIST_AES_256_OFB_CIPHER, NIST_AES_VECTOR_SIZE }, | |
205 | { 1, NIST_AES_256_KEY, CC_AES_256_BIT_KEY_SIZE, NIST_AES_OFB_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_OFB, NIST_AES_256_OFB_CIPHER, NIST_AES_PLAIN_DATA, NIST_AES_VECTOR_SIZE }, | |
206 | { 1, NIST_AES_128_KEY, CC_AES_128_BIT_KEY_SIZE, NIST_AES_CTR_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_CTR, NIST_AES_PLAIN_DATA, NIST_AES_128_CTR_CIPHER, NIST_AES_VECTOR_SIZE }, | |
207 | { 1, NIST_AES_128_KEY, CC_AES_128_BIT_KEY_SIZE, NIST_AES_CTR_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_CTR, NIST_AES_128_CTR_CIPHER, NIST_AES_PLAIN_DATA, NIST_AES_VECTOR_SIZE }, | |
208 | { 1, NIST_AES_192_KEY, CC_AES_192_BIT_KEY_SIZE, NIST_AES_CTR_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_CTR, NIST_AES_PLAIN_DATA, NIST_AES_192_CTR_CIPHER, NIST_AES_VECTOR_SIZE }, | |
209 | { 1, NIST_AES_192_KEY, CC_AES_192_BIT_KEY_SIZE, NIST_AES_CTR_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_CTR, NIST_AES_192_CTR_CIPHER, NIST_AES_PLAIN_DATA, NIST_AES_VECTOR_SIZE }, | |
210 | { 1, NIST_AES_256_KEY, CC_AES_256_BIT_KEY_SIZE, NIST_AES_CTR_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_CTR, NIST_AES_PLAIN_DATA, NIST_AES_256_CTR_CIPHER, NIST_AES_VECTOR_SIZE }, | |
211 | { 1, NIST_AES_256_KEY, CC_AES_256_BIT_KEY_SIZE, NIST_AES_CTR_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_CTR, NIST_AES_256_CTR_CIPHER, NIST_AES_PLAIN_DATA, NIST_AES_VECTOR_SIZE }, | |
212 | { 1, RFC3962_AES_128_KEY, CC_AES_128_BIT_KEY_SIZE, RFC3962_AES_CBC_CTS_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_CBC_CTS, RFC3962_AES_PLAIN_DATA, RFC3962_AES_128_CBC_CTS_CIPHER, RFC3962_AES_VECTOR_SIZE }, | |
213 | { 1, RFC3962_AES_128_KEY, CC_AES_128_BIT_KEY_SIZE, RFC3962_AES_CBC_CTS_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_CBC_CTS, RFC3962_AES_128_CBC_CTS_CIPHER, RFC3962_AES_PLAIN_DATA, RFC3962_AES_VECTOR_SIZE }, | |
214 | { 1, NIST_AES_256_XTS_KEY, CC_AES_256_BIT_KEY_SIZE, NIST_AES_256_XTS_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_XTS, NIST_AES_256_XTS_PLAIN, NIST_AES_256_XTS_CIPHER, NIST_AES_256_XTS_VECTOR_SIZE }, | |
215 | { 1, NIST_AES_256_XTS_KEY, CC_AES_256_BIT_KEY_SIZE, NIST_AES_256_XTS_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_XTS, NIST_AES_256_XTS_CIPHER, NIST_AES_256_XTS_PLAIN, NIST_AES_256_XTS_VECTOR_SIZE }, | |
216 | #if (CC_SUPPORT_SHA > 256) | |
217 | { 1, NIST_AES_512_XTS_KEY, 2*CC_AES_256_BIT_KEY_SIZE, NIST_AES_512_XTS_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_XTS, NIST_AES_512_XTS_PLAIN, NIST_AES_512_XTS_CIPHER, NIST_AES_512_XTS_VECTOR_SIZE }, | |
218 | { 1, NIST_AES_512_XTS_KEY, 2*CC_AES_256_BIT_KEY_SIZE, NIST_AES_512_XTS_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_XTS, NIST_AES_512_XTS_CIPHER, NIST_AES_512_XTS_PLAIN, NIST_AES_512_XTS_VECTOR_SIZE }, | |
219 | #endif | |
220 | /* DES */ | |
221 | { 0, NIST_TDES_ECB3_KEY, CC_DRV_DES_TRIPLE_KEY_SIZE, NIST_TDES_ECB_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_ECB, NIST_TDES_ECB3_PLAIN_DATA, NIST_TDES_ECB3_CIPHER, NIST_TDES_VECTOR_SIZE }, | |
222 | { 0, NIST_TDES_ECB3_KEY, CC_DRV_DES_TRIPLE_KEY_SIZE, NIST_TDES_ECB_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_ECB, NIST_TDES_ECB3_CIPHER, NIST_TDES_ECB3_PLAIN_DATA, NIST_TDES_VECTOR_SIZE }, | |
223 | { 0, NIST_TDES_CBC3_KEY, CC_DRV_DES_TRIPLE_KEY_SIZE, NIST_TDES_CBC3_IV, DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_CBC, NIST_TDES_CBC3_PLAIN_DATA, NIST_TDES_CBC3_CIPHER, NIST_TDES_VECTOR_SIZE }, | |
224 | { 0, NIST_TDES_CBC3_KEY, CC_DRV_DES_TRIPLE_KEY_SIZE, NIST_TDES_CBC3_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_CBC, NIST_TDES_CBC3_CIPHER, NIST_TDES_CBC3_PLAIN_DATA, NIST_TDES_VECTOR_SIZE }, | |
225 | }; | |
226 | #define FIPS_CIPHER_NUM_OF_TESTS (sizeof(FipsCipherDataTable) / sizeof(FipsCipherData)) | |
227 | ||
228 | static const FipsCmacData FipsCmacDataTable[] = { | |
229 | { DRV_CRYPTO_DIRECTION_ENCRYPT, NIST_AES_128_CMAC_KEY, AES_128_BIT_KEY_SIZE, NIST_AES_128_CMAC_PLAIN_DATA, NIST_AES_128_CMAC_VECTOR_SIZE, NIST_AES_128_CMAC_MAC, NIST_AES_128_CMAC_OUTPUT_SIZE }, | |
230 | { DRV_CRYPTO_DIRECTION_ENCRYPT, NIST_AES_192_CMAC_KEY, AES_192_BIT_KEY_SIZE, NIST_AES_192_CMAC_PLAIN_DATA, NIST_AES_192_CMAC_VECTOR_SIZE, NIST_AES_192_CMAC_MAC, NIST_AES_192_CMAC_OUTPUT_SIZE }, | |
231 | { DRV_CRYPTO_DIRECTION_ENCRYPT, NIST_AES_256_CMAC_KEY, AES_256_BIT_KEY_SIZE, NIST_AES_256_CMAC_PLAIN_DATA, NIST_AES_256_CMAC_VECTOR_SIZE, NIST_AES_256_CMAC_MAC, NIST_AES_256_CMAC_OUTPUT_SIZE }, | |
232 | }; | |
233 | #define FIPS_CMAC_NUM_OF_TESTS (sizeof(FipsCmacDataTable) / sizeof(FipsCmacData)) | |
234 | ||
235 | static const FipsHashData FipsHashDataTable[] = { | |
4f71fecd DR |
236 | { DRV_HASH_SHA1, NIST_SHA_1_MSG, NIST_SHA_MSG_SIZE, NIST_SHA_1_MD }, |
237 | { DRV_HASH_SHA256, NIST_SHA_256_MSG, NIST_SHA_MSG_SIZE, NIST_SHA_256_MD }, | |
16609980 GBY |
238 | #if (CC_SUPPORT_SHA > 256) |
239 | // { DRV_HASH_SHA512, NIST_SHA_512_MSG, NIST_SHA_MSG_SIZE, NIST_SHA_512_MD }, | |
240 | #endif | |
241 | }; | |
242 | #define FIPS_HASH_NUM_OF_TESTS (sizeof(FipsHashDataTable) / sizeof(FipsHashData)) | |
243 | ||
244 | static const FipsHmacData FipsHmacDataTable[] = { | |
4f71fecd DR |
245 | { DRV_HASH_SHA1, NIST_HMAC_SHA1_KEY, NIST_HMAC_SHA1_KEY_SIZE, NIST_HMAC_SHA1_MSG, NIST_HMAC_MSG_SIZE, NIST_HMAC_SHA1_MD }, |
246 | { DRV_HASH_SHA256, NIST_HMAC_SHA256_KEY, NIST_HMAC_SHA256_KEY_SIZE, NIST_HMAC_SHA256_MSG, NIST_HMAC_MSG_SIZE, NIST_HMAC_SHA256_MD }, | |
16609980 GBY |
247 | #if (CC_SUPPORT_SHA > 256) |
248 | // { DRV_HASH_SHA512, NIST_HMAC_SHA512_KEY, NIST_HMAC_SHA512_KEY_SIZE, NIST_HMAC_SHA512_MSG, NIST_HMAC_MSG_SIZE, NIST_HMAC_SHA512_MD }, | |
249 | #endif | |
250 | }; | |
251 | #define FIPS_HMAC_NUM_OF_TESTS (sizeof(FipsHmacDataTable) / sizeof(FipsHmacData)) | |
252 | ||
253 | static const FipsCcmData FipsCcmDataTable[] = { | |
4f71fecd DR |
254 | { DRV_CRYPTO_DIRECTION_ENCRYPT, NIST_AESCCM_128_KEY, NIST_AESCCM_128_BIT_KEY_SIZE, NIST_AESCCM_128_NONCE, NIST_AESCCM_128_ADATA, NIST_AESCCM_ADATA_SIZE, NIST_AESCCM_128_PLAIN_TEXT, NIST_AESCCM_TEXT_SIZE, NIST_AESCCM_128_CIPHER, NIST_AESCCM_TAG_SIZE, NIST_AESCCM_128_MAC }, |
255 | { DRV_CRYPTO_DIRECTION_DECRYPT, NIST_AESCCM_128_KEY, NIST_AESCCM_128_BIT_KEY_SIZE, NIST_AESCCM_128_NONCE, NIST_AESCCM_128_ADATA, NIST_AESCCM_ADATA_SIZE, NIST_AESCCM_128_CIPHER, NIST_AESCCM_TEXT_SIZE, NIST_AESCCM_128_PLAIN_TEXT, NIST_AESCCM_TAG_SIZE, NIST_AESCCM_128_MAC }, | |
256 | { DRV_CRYPTO_DIRECTION_ENCRYPT, NIST_AESCCM_192_KEY, NIST_AESCCM_192_BIT_KEY_SIZE, NIST_AESCCM_192_NONCE, NIST_AESCCM_192_ADATA, NIST_AESCCM_ADATA_SIZE, NIST_AESCCM_192_PLAIN_TEXT, NIST_AESCCM_TEXT_SIZE, NIST_AESCCM_192_CIPHER, NIST_AESCCM_TAG_SIZE, NIST_AESCCM_192_MAC }, | |
257 | { DRV_CRYPTO_DIRECTION_DECRYPT, NIST_AESCCM_192_KEY, NIST_AESCCM_192_BIT_KEY_SIZE, NIST_AESCCM_192_NONCE, NIST_AESCCM_192_ADATA, NIST_AESCCM_ADATA_SIZE, NIST_AESCCM_192_CIPHER, NIST_AESCCM_TEXT_SIZE, NIST_AESCCM_192_PLAIN_TEXT, NIST_AESCCM_TAG_SIZE, NIST_AESCCM_192_MAC }, | |
258 | { DRV_CRYPTO_DIRECTION_ENCRYPT, NIST_AESCCM_256_KEY, NIST_AESCCM_256_BIT_KEY_SIZE, NIST_AESCCM_256_NONCE, NIST_AESCCM_256_ADATA, NIST_AESCCM_ADATA_SIZE, NIST_AESCCM_256_PLAIN_TEXT, NIST_AESCCM_TEXT_SIZE, NIST_AESCCM_256_CIPHER, NIST_AESCCM_TAG_SIZE, NIST_AESCCM_256_MAC }, | |
259 | { DRV_CRYPTO_DIRECTION_DECRYPT, NIST_AESCCM_256_KEY, NIST_AESCCM_256_BIT_KEY_SIZE, NIST_AESCCM_256_NONCE, NIST_AESCCM_256_ADATA, NIST_AESCCM_ADATA_SIZE, NIST_AESCCM_256_CIPHER, NIST_AESCCM_TEXT_SIZE, NIST_AESCCM_256_PLAIN_TEXT, NIST_AESCCM_TAG_SIZE, NIST_AESCCM_256_MAC }, | |
16609980 GBY |
260 | }; |
261 | #define FIPS_CCM_NUM_OF_TESTS (sizeof(FipsCcmDataTable) / sizeof(FipsCcmData)) | |
262 | ||
263 | static const FipsGcmData FipsGcmDataTable[] = { | |
4f71fecd DR |
264 | { DRV_CRYPTO_DIRECTION_ENCRYPT, NIST_AESGCM_128_KEY, NIST_AESGCM_128_BIT_KEY_SIZE, NIST_AESGCM_128_IV, NIST_AESGCM_128_ADATA, NIST_AESGCM_ADATA_SIZE, NIST_AESGCM_128_PLAIN_TEXT, NIST_AESGCM_TEXT_SIZE, NIST_AESGCM_128_CIPHER, NIST_AESGCM_TAG_SIZE, NIST_AESGCM_128_MAC }, |
265 | { DRV_CRYPTO_DIRECTION_DECRYPT, NIST_AESGCM_128_KEY, NIST_AESGCM_128_BIT_KEY_SIZE, NIST_AESGCM_128_IV, NIST_AESGCM_128_ADATA, NIST_AESGCM_ADATA_SIZE, NIST_AESGCM_128_CIPHER, NIST_AESGCM_TEXT_SIZE, NIST_AESGCM_128_PLAIN_TEXT, NIST_AESGCM_TAG_SIZE, NIST_AESGCM_128_MAC }, | |
266 | { DRV_CRYPTO_DIRECTION_ENCRYPT, NIST_AESGCM_192_KEY, NIST_AESGCM_192_BIT_KEY_SIZE, NIST_AESGCM_192_IV, NIST_AESGCM_192_ADATA, NIST_AESGCM_ADATA_SIZE, NIST_AESGCM_192_PLAIN_TEXT, NIST_AESGCM_TEXT_SIZE, NIST_AESGCM_192_CIPHER, NIST_AESGCM_TAG_SIZE, NIST_AESGCM_192_MAC }, | |
267 | { DRV_CRYPTO_DIRECTION_DECRYPT, NIST_AESGCM_192_KEY, NIST_AESGCM_192_BIT_KEY_SIZE, NIST_AESGCM_192_IV, NIST_AESGCM_192_ADATA, NIST_AESGCM_ADATA_SIZE, NIST_AESGCM_192_CIPHER, NIST_AESGCM_TEXT_SIZE, NIST_AESGCM_192_PLAIN_TEXT, NIST_AESGCM_TAG_SIZE, NIST_AESGCM_192_MAC }, | |
268 | { DRV_CRYPTO_DIRECTION_ENCRYPT, NIST_AESGCM_256_KEY, NIST_AESGCM_256_BIT_KEY_SIZE, NIST_AESGCM_256_IV, NIST_AESGCM_256_ADATA, NIST_AESGCM_ADATA_SIZE, NIST_AESGCM_256_PLAIN_TEXT, NIST_AESGCM_TEXT_SIZE, NIST_AESGCM_256_CIPHER, NIST_AESGCM_TAG_SIZE, NIST_AESGCM_256_MAC }, | |
269 | { DRV_CRYPTO_DIRECTION_DECRYPT, NIST_AESGCM_256_KEY, NIST_AESGCM_256_BIT_KEY_SIZE, NIST_AESGCM_256_IV, NIST_AESGCM_256_ADATA, NIST_AESGCM_ADATA_SIZE, NIST_AESGCM_256_CIPHER, NIST_AESGCM_TEXT_SIZE, NIST_AESGCM_256_PLAIN_TEXT, NIST_AESGCM_TAG_SIZE, NIST_AESGCM_256_MAC }, | |
16609980 GBY |
270 | }; |
271 | #define FIPS_GCM_NUM_OF_TESTS (sizeof(FipsGcmDataTable) / sizeof(FipsGcmData)) | |
272 | ||
273 | ||
c8f17865 | 274 | static inline ssi_fips_error_t |
16609980 GBY |
275 | FIPS_CipherToFipsError(enum drv_cipher_mode mode, bool is_aes) |
276 | { | |
277 | switch (mode) | |
278 | { | |
279 | case DRV_CIPHER_ECB: | |
280 | return is_aes ? CC_REE_FIPS_ERROR_AES_ECB_PUT : CC_REE_FIPS_ERROR_DES_ECB_PUT ; | |
281 | case DRV_CIPHER_CBC: | |
282 | return is_aes ? CC_REE_FIPS_ERROR_AES_CBC_PUT : CC_REE_FIPS_ERROR_DES_CBC_PUT ; | |
283 | case DRV_CIPHER_OFB: | |
284 | return CC_REE_FIPS_ERROR_AES_OFB_PUT; | |
285 | case DRV_CIPHER_CTR: | |
286 | return CC_REE_FIPS_ERROR_AES_CTR_PUT; | |
287 | case DRV_CIPHER_CBC_CTS: | |
288 | return CC_REE_FIPS_ERROR_AES_CBC_CTS_PUT; | |
289 | case DRV_CIPHER_XTS: | |
290 | return CC_REE_FIPS_ERROR_AES_XTS_PUT; | |
291 | default: | |
292 | return CC_REE_FIPS_ERROR_GENERAL; | |
293 | } | |
294 | ||
295 | return CC_REE_FIPS_ERROR_GENERAL; | |
296 | } | |
297 | ||
298 | ||
c8f17865 | 299 | static inline int |
16609980 GBY |
300 | ssi_cipher_fips_run_test(struct ssi_drvdata *drvdata, |
301 | bool is_aes, | |
302 | int cipher_mode, | |
303 | int direction, | |
304 | dma_addr_t key_dma_addr, | |
305 | size_t key_len, | |
306 | dma_addr_t iv_dma_addr, | |
307 | size_t iv_len, | |
308 | dma_addr_t din_dma_addr, | |
309 | dma_addr_t dout_dma_addr, | |
310 | size_t data_size) | |
311 | { | |
312 | /* max number of descriptors used for the flow */ | |
313 | #define FIPS_CIPHER_MAX_SEQ_LEN 6 | |
314 | ||
315 | int rc; | |
316 | struct ssi_crypto_req ssi_req = {0}; | |
8ca57f5c | 317 | struct cc_hw_desc desc[FIPS_CIPHER_MAX_SEQ_LEN]; |
16609980 GBY |
318 | int idx = 0; |
319 | int s_flow_mode = is_aes ? S_DIN_to_AES : S_DIN_to_DES; | |
320 | ||
321 | /* create setup descriptors */ | |
322 | switch (cipher_mode) { | |
323 | case DRV_CIPHER_CBC: | |
324 | case DRV_CIPHER_CBC_CTS: | |
325 | case DRV_CIPHER_CTR: | |
326 | case DRV_CIPHER_OFB: | |
327 | /* Load cipher state */ | |
8b64e512 GBY |
328 | hw_desc_init(&desc[idx]); |
329 | set_din_type(&desc[idx], DMA_DLLI, | |
330 | iv_dma_addr, iv_len, NS_BIT); | |
331 | set_cipher_config0(&desc[idx], direction); | |
332 | set_flow_mode(&desc[idx], s_flow_mode); | |
333 | set_cipher_mode(&desc[idx], cipher_mode); | |
c8f17865 | 334 | if ((cipher_mode == DRV_CIPHER_CTR) || |
16609980 | 335 | (cipher_mode == DRV_CIPHER_OFB) ) { |
8b64e512 | 336 | set_setup_mode(&desc[idx], SETUP_LOAD_STATE1); |
16609980 | 337 | } else { |
8b64e512 | 338 | set_setup_mode(&desc[idx], SETUP_LOAD_STATE0); |
16609980 GBY |
339 | } |
340 | idx++; | |
341 | /*FALLTHROUGH*/ | |
342 | case DRV_CIPHER_ECB: | |
343 | /* Load key */ | |
8b64e512 GBY |
344 | hw_desc_init(&desc[idx]); |
345 | set_cipher_mode(&desc[idx], cipher_mode); | |
346 | set_cipher_config0(&desc[idx], direction); | |
16609980 | 347 | if (is_aes) { |
8b64e512 GBY |
348 | set_din_type(&desc[idx], DMA_DLLI, key_dma_addr, |
349 | ((key_len == 24) ? AES_MAX_KEY_SIZE : | |
350 | key_len), NS_BIT); | |
351 | set_key_size_aes(&desc[idx], key_len); | |
16609980 | 352 | } else {/*des*/ |
8b64e512 GBY |
353 | set_din_type(&desc[idx], DMA_DLLI, key_dma_addr, |
354 | key_len, NS_BIT); | |
355 | set_key_size_des(&desc[idx], key_len); | |
16609980 | 356 | } |
8b64e512 GBY |
357 | set_flow_mode(&desc[idx], s_flow_mode); |
358 | set_setup_mode(&desc[idx], SETUP_LOAD_KEY0); | |
16609980 GBY |
359 | idx++; |
360 | break; | |
361 | case DRV_CIPHER_XTS: | |
362 | /* Load AES key */ | |
8b64e512 GBY |
363 | hw_desc_init(&desc[idx]); |
364 | set_cipher_mode(&desc[idx], cipher_mode); | |
365 | set_cipher_config0(&desc[idx], direction); | |
366 | set_din_type(&desc[idx], DMA_DLLI, key_dma_addr, (key_len / 2), | |
367 | NS_BIT); | |
368 | set_key_size_aes(&desc[idx], (key_len / 2)); | |
369 | set_flow_mode(&desc[idx], s_flow_mode); | |
370 | set_setup_mode(&desc[idx], SETUP_LOAD_KEY0); | |
16609980 GBY |
371 | idx++; |
372 | ||
373 | /* load XEX key */ | |
8b64e512 GBY |
374 | hw_desc_init(&desc[idx]); |
375 | set_cipher_mode(&desc[idx], cipher_mode); | |
376 | set_cipher_config0(&desc[idx], direction); | |
377 | set_din_type(&desc[idx], DMA_DLLI, | |
378 | (key_dma_addr + (key_len / 2)), | |
379 | (key_len / 2), NS_BIT); | |
380 | set_xex_data_unit_size(&desc[idx], data_size); | |
381 | set_flow_mode(&desc[idx], s_flow_mode); | |
382 | set_key_size_aes(&desc[idx], (key_len / 2)); | |
383 | set_setup_mode(&desc[idx], SETUP_LOAD_XEX_KEY); | |
16609980 GBY |
384 | idx++; |
385 | ||
386 | /* Set state */ | |
8b64e512 GBY |
387 | hw_desc_init(&desc[idx]); |
388 | set_setup_mode(&desc[idx], SETUP_LOAD_STATE1); | |
389 | set_cipher_mode(&desc[idx], cipher_mode); | |
390 | set_cipher_config0(&desc[idx], direction); | |
391 | set_key_size_aes(&desc[idx], (key_len / 2)); | |
392 | set_flow_mode(&desc[idx], s_flow_mode); | |
393 | set_din_type(&desc[idx], DMA_DLLI, iv_dma_addr, | |
394 | CC_AES_BLOCK_SIZE, NS_BIT); | |
16609980 GBY |
395 | idx++; |
396 | break; | |
397 | default: | |
398 | FIPS_LOG("Unsupported cipher mode (%d)\n", cipher_mode); | |
399 | BUG(); | |
400 | } | |
401 | ||
402 | /* create data descriptor */ | |
8b64e512 GBY |
403 | hw_desc_init(&desc[idx]); |
404 | set_din_type(&desc[idx], DMA_DLLI, din_dma_addr, data_size, NS_BIT); | |
405 | set_dout_dlli(&desc[idx], dout_dma_addr, data_size, NS_BIT, 0); | |
406 | set_flow_mode(&desc[idx], is_aes ? DIN_AES_DOUT : DIN_DES_DOUT); | |
16609980 GBY |
407 | idx++; |
408 | ||
409 | /* perform the operation - Lock HW and push sequence */ | |
410 | BUG_ON(idx > FIPS_CIPHER_MAX_SEQ_LEN); | |
411 | rc = send_request(drvdata, &ssi_req, desc, idx, false); | |
412 | ||
413 | // send_request returns error just in some corner cases which should not appear in this flow. | |
414 | return rc; | |
415 | } | |
416 | ||
417 | ||
418 | ssi_fips_error_t | |
419 | ssi_cipher_fips_power_up_tests(struct ssi_drvdata *drvdata, void *cpu_addr_buffer, dma_addr_t dma_coherent_buffer) | |
420 | { | |
421 | ssi_fips_error_t error = CC_REE_FIPS_ERROR_OK; | |
422 | size_t i; | |
423 | struct fips_cipher_ctx *virt_ctx = (struct fips_cipher_ctx *)cpu_addr_buffer; | |
424 | ||
425 | /* set the phisical pointers for iv, key, din, dout */ | |
426 | dma_addr_t iv_dma_addr = dma_coherent_buffer + offsetof(struct fips_cipher_ctx, iv); | |
427 | dma_addr_t key_dma_addr = dma_coherent_buffer + offsetof(struct fips_cipher_ctx, key); | |
428 | dma_addr_t din_dma_addr = dma_coherent_buffer + offsetof(struct fips_cipher_ctx, din); | |
429 | dma_addr_t dout_dma_addr = dma_coherent_buffer + offsetof(struct fips_cipher_ctx, dout); | |
430 | ||
431 | for (i = 0; i < FIPS_CIPHER_NUM_OF_TESTS; ++i) | |
432 | { | |
433 | FipsCipherData *cipherData = (FipsCipherData*)&FipsCipherDataTable[i]; | |
434 | int rc = 0; | |
435 | size_t iv_size = cipherData->isAes ? NIST_AES_IV_SIZE : NIST_TDES_IV_SIZE ; | |
436 | ||
437 | memset(cpu_addr_buffer, 0, sizeof(struct fips_cipher_ctx)); | |
438 | ||
439 | /* copy into the allocated buffer */ | |
440 | memcpy(virt_ctx->iv, cipherData->iv, iv_size); | |
441 | memcpy(virt_ctx->key, cipherData->key, cipherData->keySize); | |
442 | memcpy(virt_ctx->din, cipherData->dataIn, cipherData->dataInSize); | |
443 | ||
444 | FIPS_DBG("ssi_cipher_fips_run_test - (i = %d) \n", i); | |
445 | rc = ssi_cipher_fips_run_test(drvdata, | |
446 | cipherData->isAes, | |
447 | cipherData->oprMode, | |
448 | cipherData->direction, | |
449 | key_dma_addr, | |
450 | cipherData->keySize, | |
451 | iv_dma_addr, | |
452 | iv_size, | |
453 | din_dma_addr, | |
454 | dout_dma_addr, | |
455 | cipherData->dataInSize); | |
456 | if (rc != 0) | |
457 | { | |
458 | FIPS_LOG("ssi_cipher_fips_run_test %d returned error - rc = %d \n", i, rc); | |
459 | error = FIPS_CipherToFipsError(cipherData->oprMode, cipherData->isAes); | |
460 | break; | |
461 | } | |
462 | ||
463 | /* compare actual dout to expected */ | |
464 | if (memcmp(virt_ctx->dout, cipherData->dataOut, cipherData->dataInSize) != 0) | |
465 | { | |
466 | FIPS_LOG("dout comparison error %d - oprMode=%d, isAes=%d\n", i, cipherData->oprMode, cipherData->isAes); | |
467 | FIPS_LOG(" i expected received \n"); | |
468 | FIPS_LOG(" i 0x%08x 0x%08x (size=%d) \n", (size_t)cipherData->dataOut, (size_t)virt_ctx->dout, cipherData->dataInSize); | |
469 | for (i = 0; i < cipherData->dataInSize; ++i) | |
470 | { | |
471 | FIPS_LOG(" %d 0x%02x 0x%02x \n", i, cipherData->dataOut[i], virt_ctx->dout[i]); | |
472 | } | |
473 | ||
474 | error = FIPS_CipherToFipsError(cipherData->oprMode, cipherData->isAes); | |
475 | break; | |
476 | } | |
477 | } | |
478 | ||
479 | return error; | |
480 | } | |
481 | ||
482 | ||
c8f17865 | 483 | static inline int |
16609980 GBY |
484 | ssi_cmac_fips_run_test(struct ssi_drvdata *drvdata, |
485 | dma_addr_t key_dma_addr, | |
486 | size_t key_len, | |
487 | dma_addr_t din_dma_addr, | |
488 | size_t din_len, | |
489 | dma_addr_t digest_dma_addr, | |
490 | size_t digest_len) | |
491 | { | |
492 | /* max number of descriptors used for the flow */ | |
493 | #define FIPS_CMAC_MAX_SEQ_LEN 4 | |
494 | ||
495 | int rc; | |
496 | struct ssi_crypto_req ssi_req = {0}; | |
8ca57f5c | 497 | struct cc_hw_desc desc[FIPS_CMAC_MAX_SEQ_LEN]; |
16609980 GBY |
498 | int idx = 0; |
499 | ||
500 | /* Setup CMAC Key */ | |
8b64e512 GBY |
501 | hw_desc_init(&desc[idx]); |
502 | set_din_type(&desc[idx], DMA_DLLI, key_dma_addr, | |
503 | ((key_len == 24) ? AES_MAX_KEY_SIZE : key_len), NS_BIT); | |
504 | set_setup_mode(&desc[idx], SETUP_LOAD_KEY0); | |
505 | set_cipher_mode(&desc[idx], DRV_CIPHER_CMAC); | |
506 | set_cipher_config0(&desc[idx], DESC_DIRECTION_ENCRYPT_ENCRYPT); | |
507 | set_key_size_aes(&desc[idx], key_len); | |
508 | set_flow_mode(&desc[idx], S_DIN_to_AES); | |
16609980 GBY |
509 | idx++; |
510 | ||
511 | /* Load MAC state */ | |
8b64e512 GBY |
512 | hw_desc_init(&desc[idx]); |
513 | set_din_type(&desc[idx], DMA_DLLI, digest_dma_addr, CC_AES_BLOCK_SIZE, | |
514 | NS_BIT); | |
515 | set_setup_mode(&desc[idx], SETUP_LOAD_STATE0); | |
516 | set_cipher_mode(&desc[idx], DRV_CIPHER_CMAC); | |
517 | set_cipher_config0(&desc[idx], DESC_DIRECTION_ENCRYPT_ENCRYPT); | |
518 | set_key_size_aes(&desc[idx], key_len); | |
519 | set_flow_mode(&desc[idx], S_DIN_to_AES); | |
16609980 GBY |
520 | idx++; |
521 | ||
522 | ||
523 | //ssi_hash_create_data_desc(state, ctx, DIN_AES_DOUT, desc, false, &idx); | |
8b64e512 GBY |
524 | hw_desc_init(&desc[idx]); |
525 | set_din_type(&desc[idx], DMA_DLLI, din_dma_addr, din_len, NS_BIT); | |
526 | set_flow_mode(&desc[idx], DIN_AES_DOUT); | |
16609980 | 527 | idx++; |
c8f17865 | 528 | |
16609980 | 529 | /* Get final MAC result */ |
8b64e512 GBY |
530 | hw_desc_init(&desc[idx]); |
531 | set_dout_dlli(&desc[idx], digest_dma_addr, CC_AES_BLOCK_SIZE, NS_BIT, | |
532 | 0); | |
533 | set_flow_mode(&desc[idx], S_AES_to_DOUT); | |
534 | set_setup_mode(&desc[idx], SETUP_WRITE_STATE0); | |
535 | set_cipher_config0(&desc[idx], DESC_DIRECTION_ENCRYPT_ENCRYPT); | |
536 | set_cipher_mode(&desc[idx], DRV_CIPHER_CMAC); | |
16609980 GBY |
537 | idx++; |
538 | ||
539 | /* perform the operation - Lock HW and push sequence */ | |
540 | BUG_ON(idx > FIPS_CMAC_MAX_SEQ_LEN); | |
541 | rc = send_request(drvdata, &ssi_req, desc, idx, false); | |
542 | ||
543 | // send_request returns error just in some corner cases which should not appear in this flow. | |
544 | return rc; | |
545 | } | |
546 | ||
547 | ssi_fips_error_t | |
548 | ssi_cmac_fips_power_up_tests(struct ssi_drvdata *drvdata, void *cpu_addr_buffer, dma_addr_t dma_coherent_buffer) | |
549 | { | |
550 | ssi_fips_error_t error = CC_REE_FIPS_ERROR_OK; | |
551 | size_t i; | |
552 | struct fips_cmac_ctx *virt_ctx = (struct fips_cmac_ctx *)cpu_addr_buffer; | |
553 | ||
554 | /* set the phisical pointers for key, din, dout */ | |
555 | dma_addr_t key_dma_addr = dma_coherent_buffer + offsetof(struct fips_cmac_ctx, key); | |
556 | dma_addr_t din_dma_addr = dma_coherent_buffer + offsetof(struct fips_cmac_ctx, din); | |
557 | dma_addr_t mac_res_dma_addr = dma_coherent_buffer + offsetof(struct fips_cmac_ctx, mac_res); | |
558 | ||
559 | for (i = 0; i < FIPS_CMAC_NUM_OF_TESTS; ++i) | |
560 | { | |
561 | FipsCmacData *cmac_data = (FipsCmacData*)&FipsCmacDataTable[i]; | |
562 | int rc = 0; | |
563 | ||
564 | memset(cpu_addr_buffer, 0, sizeof(struct fips_cmac_ctx)); | |
565 | ||
566 | /* copy into the allocated buffer */ | |
567 | memcpy(virt_ctx->key, cmac_data->key, cmac_data->key_size); | |
568 | memcpy(virt_ctx->din, cmac_data->data_in, cmac_data->data_in_size); | |
569 | ||
570 | BUG_ON(cmac_data->direction != DRV_CRYPTO_DIRECTION_ENCRYPT); | |
571 | ||
572 | FIPS_DBG("ssi_cmac_fips_run_test - (i = %d) \n", i); | |
573 | rc = ssi_cmac_fips_run_test(drvdata, | |
574 | key_dma_addr, | |
575 | cmac_data->key_size, | |
576 | din_dma_addr, | |
577 | cmac_data->data_in_size, | |
578 | mac_res_dma_addr, | |
579 | cmac_data->mac_res_size); | |
580 | if (rc != 0) | |
581 | { | |
582 | FIPS_LOG("ssi_cmac_fips_run_test %d returned error - rc = %d \n", i, rc); | |
583 | error = CC_REE_FIPS_ERROR_AES_CMAC_PUT; | |
584 | break; | |
585 | } | |
586 | ||
587 | /* compare actual mac result to expected */ | |
588 | if (memcmp(virt_ctx->mac_res, cmac_data->mac_res, cmac_data->mac_res_size) != 0) | |
589 | { | |
590 | FIPS_LOG("comparison error %d - digest_size=%d \n", i, cmac_data->mac_res_size); | |
591 | FIPS_LOG(" i expected received \n"); | |
592 | FIPS_LOG(" i 0x%08x 0x%08x \n", (size_t)cmac_data->mac_res, (size_t)virt_ctx->mac_res); | |
593 | for (i = 0; i < cmac_data->mac_res_size; ++i) | |
594 | { | |
595 | FIPS_LOG(" %d 0x%02x 0x%02x \n", i, cmac_data->mac_res[i], virt_ctx->mac_res[i]); | |
596 | } | |
597 | ||
598 | error = CC_REE_FIPS_ERROR_AES_CMAC_PUT; | |
599 | break; | |
600 | } | |
601 | } | |
602 | ||
603 | return error; | |
604 | } | |
605 | ||
606 | ||
c8f17865 | 607 | static inline ssi_fips_error_t |
16609980 GBY |
608 | FIPS_HashToFipsError(enum drv_hash_mode hash_mode) |
609 | { | |
610 | switch (hash_mode) { | |
611 | case DRV_HASH_SHA1: | |
612 | return CC_REE_FIPS_ERROR_SHA1_PUT; | |
613 | case DRV_HASH_SHA256: | |
614 | return CC_REE_FIPS_ERROR_SHA256_PUT; | |
615 | #if (CC_SUPPORT_SHA > 256) | |
616 | case DRV_HASH_SHA512: | |
617 | return CC_REE_FIPS_ERROR_SHA512_PUT; | |
618 | #endif | |
619 | default: | |
620 | return CC_REE_FIPS_ERROR_GENERAL; | |
621 | } | |
622 | ||
623 | return CC_REE_FIPS_ERROR_GENERAL; | |
624 | } | |
625 | ||
c8f17865 | 626 | static inline int |
16609980 GBY |
627 | ssi_hash_fips_run_test(struct ssi_drvdata *drvdata, |
628 | dma_addr_t initial_digest_dma_addr, | |
629 | dma_addr_t din_dma_addr, | |
630 | size_t data_in_size, | |
631 | dma_addr_t mac_res_dma_addr, | |
632 | enum drv_hash_mode hash_mode, | |
633 | enum drv_hash_hw_mode hw_mode, | |
634 | int digest_size, | |
635 | int inter_digestsize) | |
636 | { | |
637 | /* max number of descriptors used for the flow */ | |
638 | #define FIPS_HASH_MAX_SEQ_LEN 4 | |
639 | ||
640 | int rc; | |
641 | struct ssi_crypto_req ssi_req = {0}; | |
8ca57f5c | 642 | struct cc_hw_desc desc[FIPS_HASH_MAX_SEQ_LEN]; |
16609980 GBY |
643 | int idx = 0; |
644 | ||
645 | /* Load initial digest */ | |
8b64e512 GBY |
646 | hw_desc_init(&desc[idx]); |
647 | set_cipher_mode(&desc[idx], hw_mode); | |
648 | set_din_type(&desc[idx], DMA_DLLI, initial_digest_dma_addr, | |
649 | inter_digestsize, NS_BIT); | |
650 | set_flow_mode(&desc[idx], S_DIN_to_HASH); | |
651 | set_setup_mode(&desc[idx], SETUP_LOAD_STATE0); | |
16609980 GBY |
652 | idx++; |
653 | ||
654 | /* Load the hash current length */ | |
8b64e512 GBY |
655 | hw_desc_init(&desc[idx]); |
656 | set_cipher_mode(&desc[idx], hw_mode); | |
657 | set_din_const(&desc[idx], 0, HASH_LEN_SIZE); | |
658 | set_cipher_config1(&desc[idx], HASH_PADDING_ENABLED); | |
659 | set_flow_mode(&desc[idx], S_DIN_to_HASH); | |
660 | set_setup_mode(&desc[idx], SETUP_LOAD_KEY0); | |
16609980 GBY |
661 | idx++; |
662 | ||
663 | /* data descriptor */ | |
8b64e512 GBY |
664 | hw_desc_init(&desc[idx]); |
665 | set_din_type(&desc[idx], DMA_DLLI, din_dma_addr, data_in_size, NS_BIT); | |
666 | set_flow_mode(&desc[idx], DIN_HASH); | |
16609980 GBY |
667 | idx++; |
668 | ||
669 | /* Get final MAC result */ | |
8b64e512 GBY |
670 | hw_desc_init(&desc[idx]); |
671 | set_cipher_mode(&desc[idx], hw_mode); | |
672 | set_dout_dlli(&desc[idx], mac_res_dma_addr, digest_size, NS_BIT, 0); | |
673 | set_flow_mode(&desc[idx], S_HASH_to_DOUT); | |
674 | set_setup_mode(&desc[idx], SETUP_WRITE_STATE0); | |
675 | set_cipher_config1(&desc[idx], HASH_PADDING_DISABLED); | |
16609980 GBY |
676 | if (unlikely((hash_mode == DRV_HASH_MD5) || |
677 | (hash_mode == DRV_HASH_SHA384) || | |
678 | (hash_mode == DRV_HASH_SHA512))) { | |
8b64e512 | 679 | set_bytes_swap(&desc[idx], 1); |
16609980 | 680 | } else { |
8b64e512 GBY |
681 | set_cipher_config0(&desc[idx], |
682 | HASH_DIGEST_RESULT_LITTLE_ENDIAN); | |
16609980 GBY |
683 | } |
684 | idx++; | |
685 | ||
686 | /* perform the operation - Lock HW and push sequence */ | |
687 | BUG_ON(idx > FIPS_HASH_MAX_SEQ_LEN); | |
688 | rc = send_request(drvdata, &ssi_req, desc, idx, false); | |
689 | ||
690 | return rc; | |
691 | } | |
692 | ||
693 | ssi_fips_error_t | |
694 | ssi_hash_fips_power_up_tests(struct ssi_drvdata *drvdata, void *cpu_addr_buffer, dma_addr_t dma_coherent_buffer) | |
695 | { | |
696 | ssi_fips_error_t error = CC_REE_FIPS_ERROR_OK; | |
697 | size_t i; | |
698 | struct fips_hash_ctx *virt_ctx = (struct fips_hash_ctx *)cpu_addr_buffer; | |
699 | ||
700 | /* set the phisical pointers for initial_digest, din, mac_res */ | |
701 | dma_addr_t initial_digest_dma_addr = dma_coherent_buffer + offsetof(struct fips_hash_ctx, initial_digest); | |
702 | dma_addr_t din_dma_addr = dma_coherent_buffer + offsetof(struct fips_hash_ctx, din); | |
703 | dma_addr_t mac_res_dma_addr = dma_coherent_buffer + offsetof(struct fips_hash_ctx, mac_res); | |
704 | ||
705 | for (i = 0; i < FIPS_HASH_NUM_OF_TESTS; ++i) | |
706 | { | |
707 | FipsHashData *hash_data = (FipsHashData*)&FipsHashDataTable[i]; | |
708 | int rc = 0; | |
709 | enum drv_hash_hw_mode hw_mode = 0; | |
710 | int digest_size = 0; | |
711 | int inter_digestsize = 0; | |
712 | ||
713 | memset(cpu_addr_buffer, 0, sizeof(struct fips_hash_ctx)); | |
714 | ||
715 | switch (hash_data->hash_mode) { | |
716 | case DRV_HASH_SHA1: | |
717 | hw_mode = DRV_HASH_HW_SHA1; | |
718 | digest_size = CC_SHA1_DIGEST_SIZE; | |
719 | inter_digestsize = CC_SHA1_DIGEST_SIZE; | |
720 | /* copy the initial digest into the allocated cache coherent buffer */ | |
721 | memcpy(virt_ctx->initial_digest, (void*)sha1_init, CC_SHA1_DIGEST_SIZE); | |
722 | break; | |
723 | case DRV_HASH_SHA256: | |
724 | hw_mode = DRV_HASH_HW_SHA256; | |
725 | digest_size = CC_SHA256_DIGEST_SIZE; | |
726 | inter_digestsize = CC_SHA256_DIGEST_SIZE; | |
727 | memcpy(virt_ctx->initial_digest, (void*)sha256_init, CC_SHA256_DIGEST_SIZE); | |
728 | break; | |
729 | #if (CC_SUPPORT_SHA > 256) | |
730 | case DRV_HASH_SHA512: | |
731 | hw_mode = DRV_HASH_HW_SHA512; | |
732 | digest_size = CC_SHA512_DIGEST_SIZE; | |
733 | inter_digestsize = CC_SHA512_DIGEST_SIZE; | |
734 | memcpy(virt_ctx->initial_digest, (void*)sha512_init, CC_SHA512_DIGEST_SIZE); | |
735 | break; | |
736 | #endif | |
737 | default: | |
738 | error = FIPS_HashToFipsError(hash_data->hash_mode); | |
739 | break; | |
740 | } | |
741 | ||
742 | /* copy the din data into the allocated buffer */ | |
743 | memcpy(virt_ctx->din, hash_data->data_in, hash_data->data_in_size); | |
744 | ||
745 | /* run the test on HW */ | |
746 | FIPS_DBG("ssi_hash_fips_run_test - (i = %d) \n", i); | |
747 | rc = ssi_hash_fips_run_test(drvdata, | |
748 | initial_digest_dma_addr, | |
749 | din_dma_addr, | |
750 | hash_data->data_in_size, | |
751 | mac_res_dma_addr, | |
752 | hash_data->hash_mode, | |
753 | hw_mode, | |
754 | digest_size, | |
755 | inter_digestsize); | |
756 | if (rc != 0) | |
757 | { | |
758 | FIPS_LOG("ssi_hash_fips_run_test %d returned error - rc = %d \n", i, rc); | |
759 | error = FIPS_HashToFipsError(hash_data->hash_mode); | |
760 | break; | |
4f71fecd | 761 | } |
16609980 GBY |
762 | |
763 | /* compare actual mac result to expected */ | |
764 | if (memcmp(virt_ctx->mac_res, hash_data->mac_res, digest_size) != 0) | |
765 | { | |
766 | FIPS_LOG("comparison error %d - hash_mode=%d digest_size=%d \n", i, hash_data->hash_mode, digest_size); | |
767 | FIPS_LOG(" i expected received \n"); | |
768 | FIPS_LOG(" i 0x%08x 0x%08x \n", (size_t)hash_data->mac_res, (size_t)virt_ctx->mac_res); | |
769 | for (i = 0; i < digest_size; ++i) | |
770 | { | |
771 | FIPS_LOG(" %d 0x%02x 0x%02x \n", i, hash_data->mac_res[i], virt_ctx->mac_res[i]); | |
772 | } | |
773 | ||
774 | error = FIPS_HashToFipsError(hash_data->hash_mode); | |
775 | break; | |
4f71fecd | 776 | } |
16609980 GBY |
777 | } |
778 | ||
779 | return error; | |
780 | } | |
781 | ||
782 | ||
c8f17865 | 783 | static inline ssi_fips_error_t |
16609980 GBY |
784 | FIPS_HmacToFipsError(enum drv_hash_mode hash_mode) |
785 | { | |
786 | switch (hash_mode) { | |
787 | case DRV_HASH_SHA1: | |
788 | return CC_REE_FIPS_ERROR_HMAC_SHA1_PUT; | |
789 | case DRV_HASH_SHA256: | |
790 | return CC_REE_FIPS_ERROR_HMAC_SHA256_PUT; | |
791 | #if (CC_SUPPORT_SHA > 256) | |
792 | case DRV_HASH_SHA512: | |
793 | return CC_REE_FIPS_ERROR_HMAC_SHA512_PUT; | |
794 | #endif | |
795 | default: | |
796 | return CC_REE_FIPS_ERROR_GENERAL; | |
797 | } | |
798 | ||
799 | return CC_REE_FIPS_ERROR_GENERAL; | |
800 | } | |
801 | ||
c8f17865 | 802 | static inline int |
16609980 GBY |
803 | ssi_hmac_fips_run_test(struct ssi_drvdata *drvdata, |
804 | dma_addr_t initial_digest_dma_addr, | |
805 | dma_addr_t key_dma_addr, | |
806 | size_t key_size, | |
807 | dma_addr_t din_dma_addr, | |
808 | size_t data_in_size, | |
809 | dma_addr_t mac_res_dma_addr, | |
810 | enum drv_hash_mode hash_mode, | |
811 | enum drv_hash_hw_mode hw_mode, | |
812 | size_t digest_size, | |
813 | size_t inter_digestsize, | |
814 | size_t block_size, | |
815 | dma_addr_t k0_dma_addr, | |
816 | dma_addr_t tmp_digest_dma_addr, | |
817 | dma_addr_t digest_bytes_len_dma_addr) | |
818 | { | |
819 | /* The implemented flow is not the same as the one implemented in ssi_hash.c (setkey + digest flows). | |
161d6dd8 DR |
820 | * In this flow, there is no need to store and reload some of the intermidiate results. |
821 | */ | |
16609980 GBY |
822 | |
823 | /* max number of descriptors used for the flow */ | |
824 | #define FIPS_HMAC_MAX_SEQ_LEN 12 | |
825 | ||
826 | int rc; | |
827 | struct ssi_crypto_req ssi_req = {0}; | |
8ca57f5c | 828 | struct cc_hw_desc desc[FIPS_HMAC_MAX_SEQ_LEN]; |
16609980 GBY |
829 | int idx = 0; |
830 | int i; | |
831 | /* calc the hash opad first and ipad only afterwards (unlike the flow in ssi_hash.c) */ | |
832 | unsigned int hmacPadConst[2] = { HMAC_OPAD_CONST, HMAC_IPAD_CONST }; | |
833 | ||
834 | // assume (key_size <= block_size) | |
8b64e512 GBY |
835 | hw_desc_init(&desc[idx]); |
836 | set_din_type(&desc[idx], DMA_DLLI, key_dma_addr, key_size, NS_BIT); | |
837 | set_flow_mode(&desc[idx], BYPASS); | |
838 | set_dout_dlli(&desc[idx], k0_dma_addr, key_size, NS_BIT, 0); | |
16609980 GBY |
839 | idx++; |
840 | ||
841 | // if needed, append Key with zeros to create K0 | |
842 | if ((block_size - key_size) != 0) { | |
8b64e512 GBY |
843 | hw_desc_init(&desc[idx]); |
844 | set_din_const(&desc[idx], 0, (block_size - key_size)); | |
845 | set_flow_mode(&desc[idx], BYPASS); | |
846 | set_dout_dlli(&desc[idx], (k0_dma_addr + key_size), | |
847 | (block_size - key_size), NS_BIT, 0); | |
16609980 GBY |
848 | idx++; |
849 | } | |
850 | ||
851 | BUG_ON(idx > FIPS_HMAC_MAX_SEQ_LEN); | |
852 | rc = send_request(drvdata, &ssi_req, desc, idx, 0); | |
853 | if (unlikely(rc != 0)) { | |
854 | SSI_LOG_ERR("send_request() failed (rc=%d)\n", rc); | |
855 | return rc; | |
856 | } | |
857 | idx = 0; | |
858 | ||
859 | /* calc derived HMAC key */ | |
860 | for (i = 0; i < 2; i++) { | |
861 | /* Load hash initial state */ | |
8b64e512 GBY |
862 | hw_desc_init(&desc[idx]); |
863 | set_cipher_mode(&desc[idx], hw_mode); | |
864 | set_din_type(&desc[idx], DMA_DLLI, initial_digest_dma_addr, | |
865 | inter_digestsize, NS_BIT); | |
866 | set_flow_mode(&desc[idx], S_DIN_to_HASH); | |
867 | set_setup_mode(&desc[idx], SETUP_LOAD_STATE0); | |
16609980 GBY |
868 | idx++; |
869 | ||
870 | ||
871 | /* Load the hash current length*/ | |
8b64e512 GBY |
872 | hw_desc_init(&desc[idx]); |
873 | set_cipher_mode(&desc[idx], hw_mode); | |
874 | set_din_const(&desc[idx], 0, HASH_LEN_SIZE); | |
875 | set_flow_mode(&desc[idx], S_DIN_to_HASH); | |
876 | set_setup_mode(&desc[idx], SETUP_LOAD_KEY0); | |
16609980 GBY |
877 | idx++; |
878 | ||
879 | /* Prepare opad/ipad key */ | |
8b64e512 GBY |
880 | hw_desc_init(&desc[idx]); |
881 | set_xor_val(&desc[idx], hmacPadConst[i]); | |
882 | set_cipher_mode(&desc[idx], hw_mode); | |
883 | set_flow_mode(&desc[idx], S_DIN_to_HASH); | |
884 | set_setup_mode(&desc[idx], SETUP_LOAD_STATE1); | |
16609980 GBY |
885 | idx++; |
886 | ||
887 | /* Perform HASH update */ | |
8b64e512 GBY |
888 | hw_desc_init(&desc[idx]); |
889 | set_din_type(&desc[idx], DMA_DLLI, k0_dma_addr, block_size, | |
890 | NS_BIT); | |
891 | set_cipher_mode(&desc[idx], hw_mode); | |
892 | set_xor_active(&desc[idx]); | |
893 | set_flow_mode(&desc[idx], DIN_HASH); | |
16609980 GBY |
894 | idx++; |
895 | ||
896 | if (i == 0) { | |
897 | /* First iteration - calc H(K0^opad) into tmp_digest_dma_addr */ | |
8b64e512 GBY |
898 | hw_desc_init(&desc[idx]); |
899 | set_cipher_mode(&desc[idx], hw_mode); | |
900 | set_dout_dlli(&desc[idx], tmp_digest_dma_addr, | |
901 | inter_digestsize, NS_BIT, 0); | |
902 | set_flow_mode(&desc[idx], S_HASH_to_DOUT); | |
903 | set_setup_mode(&desc[idx], SETUP_WRITE_STATE0); | |
16609980 GBY |
904 | idx++; |
905 | ||
906 | // is this needed?? or continue with current descriptors?? | |
907 | BUG_ON(idx > FIPS_HMAC_MAX_SEQ_LEN); | |
908 | rc = send_request(drvdata, &ssi_req, desc, idx, 0); | |
909 | if (unlikely(rc != 0)) { | |
910 | SSI_LOG_ERR("send_request() failed (rc=%d)\n", rc); | |
911 | return rc; | |
912 | } | |
913 | idx = 0; | |
914 | } | |
915 | } | |
916 | ||
917 | /* data descriptor */ | |
8b64e512 GBY |
918 | hw_desc_init(&desc[idx]); |
919 | set_din_type(&desc[idx], DMA_DLLI, din_dma_addr, data_in_size, NS_BIT); | |
920 | set_flow_mode(&desc[idx], DIN_HASH); | |
16609980 GBY |
921 | idx++; |
922 | ||
923 | /* HW last hash block padding (aka. "DO_PAD") */ | |
8b64e512 GBY |
924 | hw_desc_init(&desc[idx]); |
925 | set_cipher_mode(&desc[idx], hw_mode); | |
926 | set_dout_dlli(&desc[idx], k0_dma_addr, HASH_LEN_SIZE, NS_BIT, 0); | |
927 | set_flow_mode(&desc[idx], S_HASH_to_DOUT); | |
928 | set_setup_mode(&desc[idx], SETUP_WRITE_STATE1); | |
929 | set_cipher_do(&desc[idx], DO_PAD); | |
16609980 GBY |
930 | idx++; |
931 | ||
932 | /* store the hash digest result in the context */ | |
8b64e512 GBY |
933 | hw_desc_init(&desc[idx]); |
934 | set_cipher_mode(&desc[idx], hw_mode); | |
935 | set_dout_dlli(&desc[idx], k0_dma_addr, digest_size, NS_BIT, 0); | |
936 | set_flow_mode(&desc[idx], S_HASH_to_DOUT); | |
16609980 GBY |
937 | if (unlikely((hash_mode == DRV_HASH_MD5) || |
938 | (hash_mode == DRV_HASH_SHA384) || | |
939 | (hash_mode == DRV_HASH_SHA512))) { | |
8b64e512 | 940 | set_bytes_swap(&desc[idx], 1); |
16609980 | 941 | } else { |
8b64e512 GBY |
942 | set_cipher_config0(&desc[idx], |
943 | HASH_DIGEST_RESULT_LITTLE_ENDIAN); | |
16609980 | 944 | } |
8b64e512 | 945 | set_setup_mode(&desc[idx], SETUP_WRITE_STATE0); |
16609980 GBY |
946 | idx++; |
947 | ||
948 | /* at this point: | |
161d6dd8 DR |
949 | * tmp_digest = H(o_key_pad) |
950 | * k0 = H(i_key_pad || m) | |
951 | */ | |
16609980 GBY |
952 | |
953 | /* Loading hash opad xor key state */ | |
8b64e512 GBY |
954 | hw_desc_init(&desc[idx]); |
955 | set_cipher_mode(&desc[idx], hw_mode); | |
956 | set_din_type(&desc[idx], DMA_DLLI, tmp_digest_dma_addr, | |
957 | inter_digestsize, NS_BIT); | |
958 | set_flow_mode(&desc[idx], S_DIN_to_HASH); | |
959 | set_setup_mode(&desc[idx], SETUP_LOAD_STATE0); | |
16609980 GBY |
960 | idx++; |
961 | ||
962 | /* Load the hash current length */ | |
8b64e512 GBY |
963 | hw_desc_init(&desc[idx]); |
964 | set_cipher_mode(&desc[idx], hw_mode); | |
965 | set_din_type(&desc[idx], DMA_DLLI, digest_bytes_len_dma_addr, | |
966 | HASH_LEN_SIZE, NS_BIT); | |
967 | set_cipher_config1(&desc[idx], HASH_PADDING_ENABLED); | |
968 | set_flow_mode(&desc[idx], S_DIN_to_HASH); | |
969 | set_setup_mode(&desc[idx], SETUP_LOAD_KEY0); | |
16609980 GBY |
970 | idx++; |
971 | ||
972 | /* Memory Barrier: wait for IPAD/OPAD axi write to complete */ | |
8b64e512 GBY |
973 | hw_desc_init(&desc[idx]); |
974 | set_din_no_dma(&desc[idx], 0, 0xfffff0); | |
975 | set_dout_no_dma(&desc[idx], 0, 0, 1); | |
16609980 GBY |
976 | idx++; |
977 | ||
978 | /* Perform HASH update */ | |
8b64e512 GBY |
979 | hw_desc_init(&desc[idx]); |
980 | set_din_type(&desc[idx], DMA_DLLI, k0_dma_addr, digest_size, NS_BIT); | |
981 | set_flow_mode(&desc[idx], DIN_HASH); | |
16609980 GBY |
982 | idx++; |
983 | ||
984 | ||
985 | /* Get final MAC result */ | |
8b64e512 GBY |
986 | hw_desc_init(&desc[idx]); |
987 | set_cipher_mode(&desc[idx], hw_mode); | |
988 | set_dout_dlli(&desc[idx], mac_res_dma_addr, digest_size, NS_BIT, 0); | |
989 | set_flow_mode(&desc[idx], S_HASH_to_DOUT); | |
990 | set_setup_mode(&desc[idx], SETUP_WRITE_STATE0); | |
991 | set_cipher_config1(&desc[idx], HASH_PADDING_DISABLED); | |
16609980 GBY |
992 | if (unlikely((hash_mode == DRV_HASH_MD5) || |
993 | (hash_mode == DRV_HASH_SHA384) || | |
994 | (hash_mode == DRV_HASH_SHA512))) { | |
8b64e512 | 995 | set_bytes_swap(&desc[idx], 1); |
16609980 | 996 | } else { |
8b64e512 GBY |
997 | set_cipher_config0(&desc[idx], |
998 | HASH_DIGEST_RESULT_LITTLE_ENDIAN); | |
16609980 GBY |
999 | } |
1000 | idx++; | |
1001 | ||
1002 | /* perform the operation - Lock HW and push sequence */ | |
1003 | BUG_ON(idx > FIPS_HMAC_MAX_SEQ_LEN); | |
1004 | rc = send_request(drvdata, &ssi_req, desc, idx, false); | |
1005 | ||
1006 | return rc; | |
1007 | } | |
1008 | ||
1009 | ssi_fips_error_t | |
1010 | ssi_hmac_fips_power_up_tests(struct ssi_drvdata *drvdata, void *cpu_addr_buffer, dma_addr_t dma_coherent_buffer) | |
1011 | { | |
1012 | ssi_fips_error_t error = CC_REE_FIPS_ERROR_OK; | |
1013 | size_t i; | |
1014 | struct fips_hmac_ctx *virt_ctx = (struct fips_hmac_ctx *)cpu_addr_buffer; | |
1015 | ||
1016 | /* set the phisical pointers */ | |
1017 | dma_addr_t initial_digest_dma_addr = dma_coherent_buffer + offsetof(struct fips_hmac_ctx, initial_digest); | |
1018 | dma_addr_t key_dma_addr = dma_coherent_buffer + offsetof(struct fips_hmac_ctx, key); | |
1019 | dma_addr_t k0_dma_addr = dma_coherent_buffer + offsetof(struct fips_hmac_ctx, k0); | |
1020 | dma_addr_t tmp_digest_dma_addr = dma_coherent_buffer + offsetof(struct fips_hmac_ctx, tmp_digest); | |
1021 | dma_addr_t digest_bytes_len_dma_addr = dma_coherent_buffer + offsetof(struct fips_hmac_ctx, digest_bytes_len); | |
1022 | dma_addr_t din_dma_addr = dma_coherent_buffer + offsetof(struct fips_hmac_ctx, din); | |
1023 | dma_addr_t mac_res_dma_addr = dma_coherent_buffer + offsetof(struct fips_hmac_ctx, mac_res); | |
1024 | ||
1025 | for (i = 0; i < FIPS_HMAC_NUM_OF_TESTS; ++i) | |
1026 | { | |
1027 | FipsHmacData *hmac_data = (FipsHmacData*)&FipsHmacDataTable[i]; | |
1028 | int rc = 0; | |
1029 | enum drv_hash_hw_mode hw_mode = 0; | |
1030 | int digest_size = 0; | |
1031 | int block_size = 0; | |
1032 | int inter_digestsize = 0; | |
1033 | ||
1034 | memset(cpu_addr_buffer, 0, sizeof(struct fips_hmac_ctx)); | |
1035 | ||
1036 | switch (hmac_data->hash_mode) { | |
1037 | case DRV_HASH_SHA1: | |
1038 | hw_mode = DRV_HASH_HW_SHA1; | |
1039 | digest_size = CC_SHA1_DIGEST_SIZE; | |
1040 | block_size = CC_SHA1_BLOCK_SIZE; | |
1041 | inter_digestsize = CC_SHA1_DIGEST_SIZE; | |
1042 | memcpy(virt_ctx->initial_digest, (void*)sha1_init, CC_SHA1_DIGEST_SIZE); | |
1043 | memcpy(virt_ctx->digest_bytes_len, digest_len_init, HASH_LEN_SIZE); | |
1044 | break; | |
1045 | case DRV_HASH_SHA256: | |
1046 | hw_mode = DRV_HASH_HW_SHA256; | |
1047 | digest_size = CC_SHA256_DIGEST_SIZE; | |
1048 | block_size = CC_SHA256_BLOCK_SIZE; | |
1049 | inter_digestsize = CC_SHA256_DIGEST_SIZE; | |
1050 | memcpy(virt_ctx->initial_digest, (void*)sha256_init, CC_SHA256_DIGEST_SIZE); | |
1051 | memcpy(virt_ctx->digest_bytes_len, digest_len_init, HASH_LEN_SIZE); | |
1052 | break; | |
1053 | #if (CC_SUPPORT_SHA > 256) | |
1054 | case DRV_HASH_SHA512: | |
1055 | hw_mode = DRV_HASH_HW_SHA512; | |
1056 | digest_size = CC_SHA512_DIGEST_SIZE; | |
1057 | block_size = CC_SHA512_BLOCK_SIZE; | |
1058 | inter_digestsize = CC_SHA512_DIGEST_SIZE; | |
1059 | memcpy(virt_ctx->initial_digest, (void*)sha512_init, CC_SHA512_DIGEST_SIZE); | |
1060 | memcpy(virt_ctx->digest_bytes_len, digest_len_sha512_init, HASH_LEN_SIZE); | |
1061 | break; | |
1062 | #endif | |
1063 | default: | |
1064 | error = FIPS_HmacToFipsError(hmac_data->hash_mode); | |
1065 | break; | |
1066 | } | |
1067 | ||
1068 | /* copy into the allocated buffer */ | |
1069 | memcpy(virt_ctx->key, hmac_data->key, hmac_data->key_size); | |
1070 | memcpy(virt_ctx->din, hmac_data->data_in, hmac_data->data_in_size); | |
1071 | ||
1072 | /* run the test on HW */ | |
1073 | FIPS_DBG("ssi_hmac_fips_run_test - (i = %d) \n", i); | |
1074 | rc = ssi_hmac_fips_run_test(drvdata, | |
1075 | initial_digest_dma_addr, | |
1076 | key_dma_addr, | |
1077 | hmac_data->key_size, | |
1078 | din_dma_addr, | |
1079 | hmac_data->data_in_size, | |
1080 | mac_res_dma_addr, | |
1081 | hmac_data->hash_mode, | |
1082 | hw_mode, | |
1083 | digest_size, | |
1084 | inter_digestsize, | |
1085 | block_size, | |
1086 | k0_dma_addr, | |
1087 | tmp_digest_dma_addr, | |
1088 | digest_bytes_len_dma_addr); | |
1089 | if (rc != 0) | |
1090 | { | |
1091 | FIPS_LOG("ssi_hmac_fips_run_test %d returned error - rc = %d \n", i, rc); | |
1092 | error = FIPS_HmacToFipsError(hmac_data->hash_mode); | |
1093 | break; | |
1094 | } | |
1095 | ||
1096 | /* compare actual mac result to expected */ | |
1097 | if (memcmp(virt_ctx->mac_res, hmac_data->mac_res, digest_size) != 0) | |
1098 | { | |
1099 | FIPS_LOG("comparison error %d - hash_mode=%d digest_size=%d \n", i, hmac_data->hash_mode, digest_size); | |
1100 | FIPS_LOG(" i expected received \n"); | |
1101 | FIPS_LOG(" i 0x%08x 0x%08x \n", (size_t)hmac_data->mac_res, (size_t)virt_ctx->mac_res); | |
1102 | for (i = 0; i < digest_size; ++i) | |
1103 | { | |
1104 | FIPS_LOG(" %d 0x%02x 0x%02x \n", i, hmac_data->mac_res[i], virt_ctx->mac_res[i]); | |
1105 | } | |
1106 | ||
1107 | error = FIPS_HmacToFipsError(hmac_data->hash_mode); | |
1108 | break; | |
1109 | } | |
1110 | } | |
1111 | ||
1112 | return error; | |
1113 | } | |
1114 | ||
1115 | ||
c8f17865 | 1116 | static inline int |
16609980 GBY |
1117 | ssi_ccm_fips_run_test(struct ssi_drvdata *drvdata, |
1118 | enum drv_crypto_direction direction, | |
1119 | dma_addr_t key_dma_addr, | |
1120 | size_t key_size, | |
1121 | dma_addr_t iv_dma_addr, | |
1122 | dma_addr_t ctr_cnt_0_dma_addr, | |
1123 | dma_addr_t b0_a0_adata_dma_addr, | |
1124 | size_t b0_a0_adata_size, | |
1125 | dma_addr_t din_dma_addr, | |
1126 | size_t din_size, | |
1127 | dma_addr_t dout_dma_addr, | |
1128 | dma_addr_t mac_res_dma_addr) | |
1129 | { | |
1130 | /* max number of descriptors used for the flow */ | |
1131 | #define FIPS_CCM_MAX_SEQ_LEN 10 | |
1132 | ||
1133 | int rc; | |
1134 | struct ssi_crypto_req ssi_req = {0}; | |
8ca57f5c | 1135 | struct cc_hw_desc desc[FIPS_CCM_MAX_SEQ_LEN]; |
16609980 GBY |
1136 | unsigned int idx = 0; |
1137 | unsigned int cipher_flow_mode; | |
1138 | ||
1139 | if (direction == DRV_CRYPTO_DIRECTION_DECRYPT) { | |
1140 | cipher_flow_mode = AES_to_HASH_and_DOUT; | |
1141 | } else { /* Encrypt */ | |
1142 | cipher_flow_mode = AES_and_HASH; | |
1143 | } | |
1144 | ||
1145 | /* load key */ | |
8b64e512 GBY |
1146 | hw_desc_init(&desc[idx]); |
1147 | set_cipher_mode(&desc[idx], DRV_CIPHER_CTR); | |
1148 | set_din_type(&desc[idx], DMA_DLLI, key_dma_addr, | |
1149 | ((key_size == NIST_AESCCM_192_BIT_KEY_SIZE) ? | |
1150 | CC_AES_KEY_SIZE_MAX : key_size), NS_BIT) | |
1151 | set_key_size_aes(&desc[idx], key_size); | |
1152 | set_setup_mode(&desc[idx], SETUP_LOAD_KEY0); | |
1153 | set_cipher_config0(&desc[idx], DESC_DIRECTION_ENCRYPT_ENCRYPT); | |
1154 | set_flow_mode(&desc[idx], S_DIN_to_AES); | |
16609980 GBY |
1155 | idx++; |
1156 | ||
1157 | /* load ctr state */ | |
8b64e512 GBY |
1158 | hw_desc_init(&desc[idx]); |
1159 | set_cipher_mode(&desc[idx], DRV_CIPHER_CTR); | |
1160 | set_key_size_aes(&desc[idx], key_size); | |
1161 | set_din_type(&desc[idx], DMA_DLLI, iv_dma_addr, AES_BLOCK_SIZE, | |
1162 | NS_BIT); | |
1163 | set_cipher_config0(&desc[idx], DESC_DIRECTION_ENCRYPT_ENCRYPT); | |
1164 | set_setup_mode(&desc[idx], SETUP_LOAD_STATE1); | |
1165 | set_flow_mode(&desc[idx], S_DIN_to_AES); | |
16609980 GBY |
1166 | idx++; |
1167 | ||
1168 | /* load MAC key */ | |
8b64e512 GBY |
1169 | hw_desc_init(&desc[idx]); |
1170 | set_cipher_mode(&desc[idx], DRV_CIPHER_CBC_MAC); | |
1171 | set_din_type(&desc[idx], DMA_DLLI, key_dma_addr, | |
1172 | ((key_size == NIST_AESCCM_192_BIT_KEY_SIZE) ? | |
1173 | CC_AES_KEY_SIZE_MAX : key_size), NS_BIT); | |
1174 | set_key_size_aes(&desc[idx], key_size); | |
1175 | set_setup_mode(&desc[idx], SETUP_LOAD_KEY0); | |
1176 | set_cipher_config0(&desc[idx], DESC_DIRECTION_ENCRYPT_ENCRYPT); | |
1177 | set_flow_mode(&desc[idx], S_DIN_to_HASH); | |
1178 | set_aes_not_hash_mode(&desc[idx]); | |
16609980 GBY |
1179 | idx++; |
1180 | ||
1181 | /* load MAC state */ | |
8b64e512 GBY |
1182 | hw_desc_init(&desc[idx]); |
1183 | set_cipher_mode(&desc[idx], DRV_CIPHER_CBC_MAC); | |
1184 | set_key_size_aes(&desc[idx], key_size); | |
1185 | set_din_type(&desc[idx], DMA_DLLI, mac_res_dma_addr, | |
1186 | NIST_AESCCM_TAG_SIZE, NS_BIT); | |
1187 | set_cipher_config0(&desc[idx], DESC_DIRECTION_ENCRYPT_ENCRYPT); | |
1188 | set_setup_mode(&desc[idx], SETUP_LOAD_STATE0); | |
1189 | set_flow_mode(&desc[idx], S_DIN_to_HASH); | |
1190 | set_aes_not_hash_mode(&desc[idx]); | |
16609980 GBY |
1191 | idx++; |
1192 | ||
1193 | /* prcess assoc data */ | |
8b64e512 GBY |
1194 | hw_desc_init(&desc[idx]); |
1195 | set_din_type(&desc[idx], DMA_DLLI, b0_a0_adata_dma_addr, | |
1196 | b0_a0_adata_size, NS_BIT); | |
1197 | set_flow_mode(&desc[idx], DIN_HASH); | |
16609980 GBY |
1198 | idx++; |
1199 | ||
1200 | /* process the cipher */ | |
8b64e512 GBY |
1201 | hw_desc_init(&desc[idx]); |
1202 | set_din_type(&desc[idx], DMA_DLLI, din_dma_addr, din_size, NS_BIT); | |
1203 | set_dout_dlli(&desc[idx], dout_dma_addr, din_size, NS_BIT, 0); | |
1204 | set_flow_mode(&desc[idx], cipher_flow_mode); | |
16609980 GBY |
1205 | idx++; |
1206 | ||
1207 | /* Read temporal MAC */ | |
8b64e512 GBY |
1208 | hw_desc_init(&desc[idx]); |
1209 | set_cipher_mode(&desc[idx], DRV_CIPHER_CBC_MAC); | |
1210 | set_dout_dlli(&desc[idx], mac_res_dma_addr, NIST_AESCCM_TAG_SIZE, | |
1211 | NS_BIT, 0); | |
1212 | set_setup_mode(&desc[idx], SETUP_WRITE_STATE0); | |
1213 | set_cipher_config0(&desc[idx], HASH_DIGEST_RESULT_LITTLE_ENDIAN); | |
1214 | set_flow_mode(&desc[idx], S_HASH_to_DOUT); | |
1215 | set_aes_not_hash_mode(&desc[idx]); | |
16609980 GBY |
1216 | idx++; |
1217 | ||
1218 | /* load AES-CTR state (for last MAC calculation)*/ | |
8b64e512 GBY |
1219 | hw_desc_init(&desc[idx]); |
1220 | set_cipher_mode(&desc[idx], DRV_CIPHER_CTR); | |
1221 | set_cipher_config0(&desc[idx], DRV_CRYPTO_DIRECTION_ENCRYPT); | |
1222 | set_din_type(&desc[idx], DMA_DLLI, ctr_cnt_0_dma_addr, AES_BLOCK_SIZE, | |
1223 | NS_BIT); | |
1224 | set_key_size_aes(&desc[idx], key_size); | |
1225 | set_setup_mode(&desc[idx], SETUP_LOAD_STATE1); | |
1226 | set_flow_mode(&desc[idx], S_DIN_to_AES); | |
16609980 GBY |
1227 | idx++; |
1228 | ||
1229 | /* Memory Barrier */ | |
8b64e512 GBY |
1230 | hw_desc_init(&desc[idx]); |
1231 | set_din_no_dma(&desc[idx], 0, 0xfffff0); | |
1232 | set_dout_no_dma(&desc[idx], 0, 0, 1); | |
16609980 GBY |
1233 | idx++; |
1234 | ||
1235 | /* encrypt the "T" value and store MAC inplace */ | |
8b64e512 GBY |
1236 | hw_desc_init(&desc[idx]); |
1237 | set_din_type(&desc[idx], DMA_DLLI, mac_res_dma_addr, | |
1238 | NIST_AESCCM_TAG_SIZE, NS_BIT); | |
1239 | set_dout_dlli(&desc[idx], mac_res_dma_addr, NIST_AESCCM_TAG_SIZE, | |
1240 | NS_BIT, 0); | |
1241 | set_flow_mode(&desc[idx], DIN_AES_DOUT); | |
c8f17865 | 1242 | idx++; |
16609980 GBY |
1243 | |
1244 | /* perform the operation - Lock HW and push sequence */ | |
1245 | BUG_ON(idx > FIPS_CCM_MAX_SEQ_LEN); | |
1246 | rc = send_request(drvdata, &ssi_req, desc, idx, false); | |
1247 | ||
1248 | return rc; | |
1249 | } | |
1250 | ||
1251 | ssi_fips_error_t | |
1252 | ssi_ccm_fips_power_up_tests(struct ssi_drvdata *drvdata, void *cpu_addr_buffer, dma_addr_t dma_coherent_buffer) | |
1253 | { | |
1254 | ssi_fips_error_t error = CC_REE_FIPS_ERROR_OK; | |
1255 | size_t i; | |
1256 | struct fips_ccm_ctx *virt_ctx = (struct fips_ccm_ctx *)cpu_addr_buffer; | |
1257 | ||
1258 | /* set the phisical pointers */ | |
1259 | dma_addr_t b0_a0_adata_dma_addr = dma_coherent_buffer + offsetof(struct fips_ccm_ctx, b0_a0_adata); | |
1260 | dma_addr_t iv_dma_addr = dma_coherent_buffer + offsetof(struct fips_ccm_ctx, iv); | |
1261 | dma_addr_t ctr_cnt_0_dma_addr = dma_coherent_buffer + offsetof(struct fips_ccm_ctx, ctr_cnt_0); | |
1262 | dma_addr_t key_dma_addr = dma_coherent_buffer + offsetof(struct fips_ccm_ctx, key); | |
1263 | dma_addr_t din_dma_addr = dma_coherent_buffer + offsetof(struct fips_ccm_ctx, din); | |
1264 | dma_addr_t dout_dma_addr = dma_coherent_buffer + offsetof(struct fips_ccm_ctx, dout); | |
1265 | dma_addr_t mac_res_dma_addr = dma_coherent_buffer + offsetof(struct fips_ccm_ctx, mac_res); | |
1266 | ||
1267 | for (i = 0; i < FIPS_CCM_NUM_OF_TESTS; ++i) | |
1268 | { | |
1269 | FipsCcmData *ccmData = (FipsCcmData*)&FipsCcmDataTable[i]; | |
1270 | int rc = 0; | |
1271 | ||
1272 | memset(cpu_addr_buffer, 0, sizeof(struct fips_ccm_ctx)); | |
1273 | ||
1274 | /* copy the nonce, key, adata, din data into the allocated buffer */ | |
1275 | memcpy(virt_ctx->key, ccmData->key, ccmData->keySize); | |
1276 | memcpy(virt_ctx->din, ccmData->dataIn, ccmData->dataInSize); | |
1277 | { | |
1278 | /* build B0 -- B0, nonce, l(m) */ | |
1279 | __be16 data = cpu_to_be16(NIST_AESCCM_TEXT_SIZE); | |
1280 | virt_ctx->b0_a0_adata[0] = NIST_AESCCM_B0_VAL; | |
1281 | memcpy(virt_ctx->b0_a0_adata + 1, ccmData->nonce, NIST_AESCCM_NONCE_SIZE); | |
1282 | memcpy(virt_ctx->b0_a0_adata + 14, (u8 *)&data, sizeof(__be16)); | |
1283 | /* build A0+ADATA */ | |
1284 | virt_ctx->b0_a0_adata[NIST_AESCCM_IV_SIZE + 0] = (ccmData->adataSize >> 8) & 0xFF; | |
1285 | virt_ctx->b0_a0_adata[NIST_AESCCM_IV_SIZE + 1] = ccmData->adataSize & 0xFF; | |
1286 | memcpy(virt_ctx->b0_a0_adata + NIST_AESCCM_IV_SIZE + 2, ccmData->adata, ccmData->adataSize); | |
1287 | /* iv */ | |
1288 | virt_ctx->iv[0] = 1; /* L' */ | |
1289 | memcpy(virt_ctx->iv + 1, ccmData->nonce, NIST_AESCCM_NONCE_SIZE); | |
1290 | virt_ctx->iv[15] = 1; | |
1291 | /* ctr_count_0 */ | |
1292 | memcpy(virt_ctx->ctr_cnt_0, virt_ctx->iv, NIST_AESCCM_IV_SIZE); | |
1293 | virt_ctx->ctr_cnt_0[15] = 0; | |
1294 | } | |
1295 | ||
1296 | FIPS_DBG("ssi_ccm_fips_run_test - (i = %d) \n", i); | |
1297 | rc = ssi_ccm_fips_run_test(drvdata, | |
1298 | ccmData->direction, | |
1299 | key_dma_addr, | |
1300 | ccmData->keySize, | |
1301 | iv_dma_addr, | |
1302 | ctr_cnt_0_dma_addr, | |
1303 | b0_a0_adata_dma_addr, | |
1304 | FIPS_CCM_B0_A0_ADATA_SIZE, | |
1305 | din_dma_addr, | |
1306 | ccmData->dataInSize, | |
1307 | dout_dma_addr, | |
1308 | mac_res_dma_addr); | |
1309 | if (rc != 0) | |
1310 | { | |
1311 | FIPS_LOG("ssi_ccm_fips_run_test %d returned error - rc = %d \n", i, rc); | |
1312 | error = CC_REE_FIPS_ERROR_AESCCM_PUT; | |
1313 | break; | |
1314 | } | |
1315 | ||
1316 | /* compare actual dout to expected */ | |
1317 | if (memcmp(virt_ctx->dout, ccmData->dataOut, ccmData->dataInSize) != 0) | |
1318 | { | |
1319 | FIPS_LOG("dout comparison error %d - size=%d \n", i, ccmData->dataInSize); | |
4f71fecd | 1320 | error = CC_REE_FIPS_ERROR_AESCCM_PUT; |
16609980 | 1321 | break; |
4f71fecd | 1322 | } |
16609980 GBY |
1323 | |
1324 | /* compare actual mac result to expected */ | |
1325 | if (memcmp(virt_ctx->mac_res, ccmData->macResOut, ccmData->tagSize) != 0) | |
1326 | { | |
1327 | FIPS_LOG("mac_res comparison error %d - mac_size=%d \n", i, ccmData->tagSize); | |
1328 | FIPS_LOG(" i expected received \n"); | |
1329 | FIPS_LOG(" i 0x%08x 0x%08x \n", (size_t)ccmData->macResOut, (size_t)virt_ctx->mac_res); | |
1330 | for (i = 0; i < ccmData->tagSize; ++i) | |
1331 | { | |
1332 | FIPS_LOG(" %d 0x%02x 0x%02x \n", i, ccmData->macResOut[i], virt_ctx->mac_res[i]); | |
1333 | } | |
1334 | ||
1335 | error = CC_REE_FIPS_ERROR_AESCCM_PUT; | |
1336 | break; | |
1337 | } | |
1338 | } | |
1339 | ||
1340 | return error; | |
1341 | } | |
1342 | ||
1343 | ||
1344 | static inline int | |
1345 | ssi_gcm_fips_run_test(struct ssi_drvdata *drvdata, | |
1346 | enum drv_crypto_direction direction, | |
1347 | dma_addr_t key_dma_addr, | |
1348 | size_t key_size, | |
1349 | dma_addr_t hkey_dma_addr, | |
1350 | dma_addr_t block_len_dma_addr, | |
1351 | dma_addr_t iv_inc1_dma_addr, | |
1352 | dma_addr_t iv_inc2_dma_addr, | |
1353 | dma_addr_t adata_dma_addr, | |
1354 | size_t adata_size, | |
1355 | dma_addr_t din_dma_addr, | |
1356 | size_t din_size, | |
1357 | dma_addr_t dout_dma_addr, | |
1358 | dma_addr_t mac_res_dma_addr) | |
1359 | { | |
1360 | /* max number of descriptors used for the flow */ | |
1361 | #define FIPS_GCM_MAX_SEQ_LEN 15 | |
1362 | ||
1363 | int rc; | |
1364 | struct ssi_crypto_req ssi_req = {0}; | |
8ca57f5c | 1365 | struct cc_hw_desc desc[FIPS_GCM_MAX_SEQ_LEN]; |
16609980 GBY |
1366 | unsigned int idx = 0; |
1367 | unsigned int cipher_flow_mode; | |
1368 | ||
1369 | if (direction == DRV_CRYPTO_DIRECTION_DECRYPT) { | |
1370 | cipher_flow_mode = AES_and_HASH; | |
1371 | } else { /* Encrypt */ | |
1372 | cipher_flow_mode = AES_to_HASH_and_DOUT; | |
1373 | } | |
1374 | ||
1375 | ///////////////////////////////// 1 //////////////////////////////////// | |
1376 | // ssi_aead_gcm_setup_ghash_desc(req, desc, seq_size); | |
1377 | ///////////////////////////////// 1 //////////////////////////////////// | |
1378 | ||
8b64e512 GBY |
1379 | /* load key to AES */ |
1380 | hw_desc_init(&desc[idx]); | |
1381 | set_cipher_mode(&desc[idx], DRV_CIPHER_ECB); | |
1382 | set_cipher_config0(&desc[idx], DRV_CRYPTO_DIRECTION_ENCRYPT); | |
1383 | set_din_type(&desc[idx], DMA_DLLI, key_dma_addr, key_size, NS_BIT); | |
1384 | set_key_size_aes(&desc[idx], key_size); | |
1385 | set_setup_mode(&desc[idx], SETUP_LOAD_KEY0); | |
1386 | set_flow_mode(&desc[idx], S_DIN_to_AES); | |
16609980 GBY |
1387 | idx++; |
1388 | ||
1389 | /* process one zero block to generate hkey */ | |
8b64e512 GBY |
1390 | hw_desc_init(&desc[idx]); |
1391 | set_din_const(&desc[idx], 0x0, AES_BLOCK_SIZE); | |
1392 | set_dout_dlli(&desc[idx], hkey_dma_addr, AES_BLOCK_SIZE, NS_BIT, 0); | |
1393 | set_flow_mode(&desc[idx], DIN_AES_DOUT); | |
16609980 GBY |
1394 | idx++; |
1395 | ||
1396 | /* Memory Barrier */ | |
8b64e512 GBY |
1397 | hw_desc_init(&desc[idx]); |
1398 | set_din_no_dma(&desc[idx], 0, 0xfffff0); | |
1399 | set_dout_no_dma(&desc[idx], 0, 0, 1); | |
16609980 GBY |
1400 | idx++; |
1401 | ||
1402 | /* Load GHASH subkey */ | |
8b64e512 GBY |
1403 | hw_desc_init(&desc[idx]); |
1404 | set_din_type(&desc[idx], DMA_DLLI, hkey_dma_addr, AES_BLOCK_SIZE, | |
1405 | NS_BIT); | |
1406 | set_dout_no_dma(&desc[idx], 0, 0, 1); | |
1407 | set_flow_mode(&desc[idx], S_DIN_to_HASH); | |
1408 | set_aes_not_hash_mode(&desc[idx]); | |
1409 | set_cipher_mode(&desc[idx], DRV_HASH_HW_GHASH); | |
1410 | set_cipher_config1(&desc[idx], HASH_PADDING_ENABLED); | |
1411 | set_setup_mode(&desc[idx], SETUP_LOAD_KEY0); | |
16609980 GBY |
1412 | idx++; |
1413 | ||
1414 | /* Configure Hash Engine to work with GHASH. | |
161d6dd8 DR |
1415 | * Since it was not possible to extend HASH submodes to add GHASH, |
1416 | * The following command is necessary in order to | |
1417 | * select GHASH (according to HW designers) | |
1418 | */ | |
8b64e512 GBY |
1419 | hw_desc_init(&desc[idx]); |
1420 | set_din_no_dma(&desc[idx], 0, 0xfffff0); | |
1421 | set_dout_no_dma(&desc[idx], 0, 0, 1); | |
1422 | set_flow_mode(&desc[idx], S_DIN_to_HASH); | |
1423 | set_aes_not_hash_mode(&desc[idx]); | |
1424 | set_cipher_mode(&desc[idx], DRV_HASH_HW_GHASH); | |
1425 | set_cipher_do(&desc[idx], 1); //1=AES_SK RKEK | |
1426 | set_cipher_config0(&desc[idx], DRV_CRYPTO_DIRECTION_ENCRYPT); | |
1427 | set_cipher_config1(&desc[idx], HASH_PADDING_ENABLED); | |
1428 | set_setup_mode(&desc[idx], SETUP_LOAD_KEY0); | |
16609980 GBY |
1429 | idx++; |
1430 | ||
1431 | /* Load GHASH initial STATE (which is 0). (for any hash there is an initial state) */ | |
8b64e512 GBY |
1432 | hw_desc_init(&desc[idx]); |
1433 | set_din_const(&desc[idx], 0x0, AES_BLOCK_SIZE); | |
1434 | set_dout_no_dma(&desc[idx], 0, 0, 1); | |
1435 | set_flow_mode(&desc[idx], S_DIN_to_HASH); | |
1436 | set_aes_not_hash_mode(&desc[idx]); | |
1437 | set_cipher_mode(&desc[idx], DRV_HASH_HW_GHASH); | |
1438 | set_cipher_config1(&desc[idx], HASH_PADDING_ENABLED); | |
1439 | set_setup_mode(&desc[idx], SETUP_LOAD_STATE0); | |
16609980 GBY |
1440 | idx++; |
1441 | ||
1442 | ||
1443 | ||
1444 | ///////////////////////////////// 2 //////////////////////////////////// | |
1445 | /* prcess(ghash) assoc data */ | |
1446 | // if (req->assoclen > 0) | |
1447 | // ssi_aead_create_assoc_desc(req, DIN_HASH, desc, seq_size); | |
1448 | ///////////////////////////////// 2 //////////////////////////////////// | |
1449 | ||
8b64e512 GBY |
1450 | hw_desc_init(&desc[idx]); |
1451 | set_din_type(&desc[idx], DMA_DLLI, adata_dma_addr, adata_size, NS_BIT); | |
1452 | set_flow_mode(&desc[idx], DIN_HASH); | |
16609980 GBY |
1453 | idx++; |
1454 | ||
1455 | ||
1456 | ///////////////////////////////// 3 //////////////////////////////////// | |
1457 | // ssi_aead_gcm_setup_gctr_desc(req, desc, seq_size); | |
1458 | ///////////////////////////////// 3 //////////////////////////////////// | |
1459 | ||
1460 | /* load key to AES*/ | |
8b64e512 GBY |
1461 | hw_desc_init(&desc[idx]); |
1462 | set_cipher_mode(&desc[idx], DRV_CIPHER_GCTR); | |
1463 | set_cipher_config0(&desc[idx], DRV_CRYPTO_DIRECTION_ENCRYPT); | |
1464 | set_din_type(&desc[idx], DMA_DLLI, key_dma_addr, key_size, NS_BIT); | |
1465 | set_key_size_aes(&desc[idx], key_size); | |
1466 | set_setup_mode(&desc[idx], SETUP_LOAD_KEY0); | |
1467 | set_flow_mode(&desc[idx], S_DIN_to_AES); | |
16609980 GBY |
1468 | idx++; |
1469 | ||
1470 | /* load AES/CTR initial CTR value inc by 2*/ | |
8b64e512 GBY |
1471 | hw_desc_init(&desc[idx]); |
1472 | set_cipher_mode(&desc[idx], DRV_CIPHER_GCTR); | |
1473 | set_key_size_aes(&desc[idx], key_size); | |
1474 | set_din_type(&desc[idx], DMA_DLLI, iv_inc2_dma_addr, AES_BLOCK_SIZE, | |
1475 | NS_BIT); | |
1476 | set_cipher_config0(&desc[idx], DRV_CRYPTO_DIRECTION_ENCRYPT); | |
1477 | set_setup_mode(&desc[idx], SETUP_LOAD_STATE1); | |
1478 | set_flow_mode(&desc[idx], S_DIN_to_AES); | |
16609980 GBY |
1479 | idx++; |
1480 | ||
1481 | ||
1482 | ///////////////////////////////// 4 //////////////////////////////////// | |
1483 | /* process(gctr+ghash) */ | |
1484 | // if (req_ctx->cryptlen != 0) | |
c8f17865 | 1485 | // ssi_aead_process_cipher_data_desc(req, cipher_flow_mode, desc, seq_size); |
16609980 GBY |
1486 | ///////////////////////////////// 4 //////////////////////////////////// |
1487 | ||
8b64e512 GBY |
1488 | hw_desc_init(&desc[idx]); |
1489 | set_din_type(&desc[idx], DMA_DLLI, din_dma_addr, din_size, NS_BIT); | |
1490 | set_dout_dlli(&desc[idx], dout_dma_addr, din_size, NS_BIT, 0); | |
1491 | set_flow_mode(&desc[idx], cipher_flow_mode); | |
16609980 GBY |
1492 | idx++; |
1493 | ||
1494 | ||
1495 | ///////////////////////////////// 5 //////////////////////////////////// | |
1496 | // ssi_aead_process_gcm_result_desc(req, desc, seq_size); | |
1497 | ///////////////////////////////// 5 //////////////////////////////////// | |
1498 | ||
1499 | /* prcess(ghash) gcm_block_len */ | |
8b64e512 GBY |
1500 | hw_desc_init(&desc[idx]); |
1501 | set_din_type(&desc[idx], DMA_DLLI, block_len_dma_addr, AES_BLOCK_SIZE, | |
1502 | NS_BIT); | |
1503 | set_flow_mode(&desc[idx], DIN_HASH); | |
16609980 GBY |
1504 | idx++; |
1505 | ||
1506 | /* Store GHASH state after GHASH(Associated Data + Cipher +LenBlock) */ | |
8b64e512 GBY |
1507 | hw_desc_init(&desc[idx]); |
1508 | set_cipher_mode(&desc[idx], DRV_HASH_HW_GHASH); | |
1509 | set_din_no_dma(&desc[idx], 0, 0xfffff0); | |
1510 | set_dout_dlli(&desc[idx], mac_res_dma_addr, AES_BLOCK_SIZE, NS_BIT, 0); | |
1511 | set_setup_mode(&desc[idx], SETUP_WRITE_STATE0); | |
1512 | set_flow_mode(&desc[idx], S_HASH_to_DOUT); | |
1513 | set_aes_not_hash_mode(&desc[idx]); | |
c8f17865 | 1514 | idx++; |
16609980 GBY |
1515 | |
1516 | /* load AES/CTR initial CTR value inc by 1*/ | |
8b64e512 GBY |
1517 | hw_desc_init(&desc[idx]); |
1518 | set_cipher_mode(&desc[idx], DRV_CIPHER_GCTR); | |
1519 | set_key_size_aes(&desc[idx], key_size); | |
1520 | set_din_type(&desc[idx], DMA_DLLI, iv_inc1_dma_addr, AES_BLOCK_SIZE, | |
1521 | NS_BIT); | |
1522 | set_cipher_config0(&desc[idx], DRV_CRYPTO_DIRECTION_ENCRYPT); | |
1523 | set_setup_mode(&desc[idx], SETUP_LOAD_STATE1); | |
1524 | set_flow_mode(&desc[idx], S_DIN_to_AES); | |
16609980 GBY |
1525 | idx++; |
1526 | ||
1527 | /* Memory Barrier */ | |
8b64e512 GBY |
1528 | hw_desc_init(&desc[idx]); |
1529 | set_din_no_dma(&desc[idx], 0, 0xfffff0); | |
1530 | set_dout_no_dma(&desc[idx], 0, 0, 1); | |
16609980 GBY |
1531 | idx++; |
1532 | ||
1533 | /* process GCTR on stored GHASH and store MAC inplace */ | |
8b64e512 GBY |
1534 | hw_desc_init(&desc[idx]); |
1535 | set_cipher_mode(&desc[idx], DRV_CIPHER_GCTR); | |
1536 | set_din_type(&desc[idx], DMA_DLLI, mac_res_dma_addr, AES_BLOCK_SIZE, | |
1537 | NS_BIT); | |
1538 | set_dout_dlli(&desc[idx], mac_res_dma_addr, AES_BLOCK_SIZE, NS_BIT, 0); | |
1539 | set_flow_mode(&desc[idx], DIN_AES_DOUT); | |
16609980 GBY |
1540 | idx++; |
1541 | ||
1542 | /* perform the operation - Lock HW and push sequence */ | |
1543 | BUG_ON(idx > FIPS_GCM_MAX_SEQ_LEN); | |
1544 | rc = send_request(drvdata, &ssi_req, desc, idx, false); | |
1545 | ||
1546 | return rc; | |
1547 | } | |
1548 | ||
1549 | ssi_fips_error_t | |
1550 | ssi_gcm_fips_power_up_tests(struct ssi_drvdata *drvdata, void *cpu_addr_buffer, dma_addr_t dma_coherent_buffer) | |
1551 | { | |
1552 | ssi_fips_error_t error = CC_REE_FIPS_ERROR_OK; | |
1553 | size_t i; | |
1554 | struct fips_gcm_ctx *virt_ctx = (struct fips_gcm_ctx *)cpu_addr_buffer; | |
1555 | ||
1556 | /* set the phisical pointers */ | |
1557 | dma_addr_t adata_dma_addr = dma_coherent_buffer + offsetof(struct fips_gcm_ctx, adata); | |
1558 | dma_addr_t key_dma_addr = dma_coherent_buffer + offsetof(struct fips_gcm_ctx, key); | |
1559 | dma_addr_t hkey_dma_addr = dma_coherent_buffer + offsetof(struct fips_gcm_ctx, hkey); | |
1560 | dma_addr_t din_dma_addr = dma_coherent_buffer + offsetof(struct fips_gcm_ctx, din); | |
1561 | dma_addr_t dout_dma_addr = dma_coherent_buffer + offsetof(struct fips_gcm_ctx, dout); | |
1562 | dma_addr_t mac_res_dma_addr = dma_coherent_buffer + offsetof(struct fips_gcm_ctx, mac_res); | |
1563 | dma_addr_t len_block_dma_addr = dma_coherent_buffer + offsetof(struct fips_gcm_ctx, len_block); | |
1564 | dma_addr_t iv_inc1_dma_addr = dma_coherent_buffer + offsetof(struct fips_gcm_ctx, iv_inc1); | |
1565 | dma_addr_t iv_inc2_dma_addr = dma_coherent_buffer + offsetof(struct fips_gcm_ctx, iv_inc2); | |
1566 | ||
1567 | for (i = 0; i < FIPS_GCM_NUM_OF_TESTS; ++i) | |
1568 | { | |
1569 | FipsGcmData *gcmData = (FipsGcmData*)&FipsGcmDataTable[i]; | |
1570 | int rc = 0; | |
1571 | ||
1572 | memset(cpu_addr_buffer, 0, sizeof(struct fips_gcm_ctx)); | |
1573 | ||
1574 | /* copy the key, adata, din data - into the allocated buffer */ | |
1575 | memcpy(virt_ctx->key, gcmData->key, gcmData->keySize); | |
1576 | memcpy(virt_ctx->adata, gcmData->adata, gcmData->adataSize); | |
1577 | memcpy(virt_ctx->din, gcmData->dataIn, gcmData->dataInSize); | |
1578 | ||
1579 | /* len_block */ | |
1580 | { | |
1581 | __be64 len_bits; | |
1582 | len_bits = cpu_to_be64(gcmData->adataSize * 8); | |
1583 | memcpy(virt_ctx->len_block, &len_bits, sizeof(len_bits)); | |
1584 | len_bits = cpu_to_be64(gcmData->dataInSize * 8); | |
1585 | memcpy(virt_ctx->len_block + 8, &len_bits, sizeof(len_bits)); | |
1586 | } | |
1587 | /* iv_inc1, iv_inc2 */ | |
1588 | { | |
1589 | __be32 counter = cpu_to_be32(1); | |
1590 | memcpy(virt_ctx->iv_inc1, gcmData->iv, NIST_AESGCM_IV_SIZE); | |
1591 | memcpy(virt_ctx->iv_inc1 + NIST_AESGCM_IV_SIZE, &counter, sizeof(counter)); | |
1592 | counter = cpu_to_be32(2); | |
1593 | memcpy(virt_ctx->iv_inc2, gcmData->iv, NIST_AESGCM_IV_SIZE); | |
1594 | memcpy(virt_ctx->iv_inc2 + NIST_AESGCM_IV_SIZE, &counter, sizeof(counter)); | |
1595 | } | |
1596 | ||
1597 | FIPS_DBG("ssi_gcm_fips_run_test - (i = %d) \n", i); | |
1598 | rc = ssi_gcm_fips_run_test(drvdata, | |
1599 | gcmData->direction, | |
1600 | key_dma_addr, | |
1601 | gcmData->keySize, | |
1602 | hkey_dma_addr, | |
1603 | len_block_dma_addr, | |
1604 | iv_inc1_dma_addr, | |
1605 | iv_inc2_dma_addr, | |
1606 | adata_dma_addr, | |
1607 | gcmData->adataSize, | |
1608 | din_dma_addr, | |
1609 | gcmData->dataInSize, | |
1610 | dout_dma_addr, | |
1611 | mac_res_dma_addr); | |
1612 | if (rc != 0) | |
1613 | { | |
1614 | FIPS_LOG("ssi_gcm_fips_run_test %d returned error - rc = %d \n", i, rc); | |
1615 | error = CC_REE_FIPS_ERROR_AESGCM_PUT; | |
1616 | break; | |
1617 | } | |
1618 | ||
1619 | if (gcmData->direction == DRV_CRYPTO_DIRECTION_ENCRYPT) { | |
1620 | /* compare actual dout to expected */ | |
1621 | if (memcmp(virt_ctx->dout, gcmData->dataOut, gcmData->dataInSize) != 0) | |
1622 | { | |
1623 | FIPS_LOG("dout comparison error %d - size=%d \n", i, gcmData->dataInSize); | |
1624 | FIPS_LOG(" i expected received \n"); | |
1625 | FIPS_LOG(" i 0x%08x 0x%08x \n", (size_t)gcmData->dataOut, (size_t)virt_ctx->dout); | |
1626 | for (i = 0; i < gcmData->dataInSize; ++i) | |
1627 | { | |
1628 | FIPS_LOG(" %d 0x%02x 0x%02x \n", i, gcmData->dataOut[i], virt_ctx->dout[i]); | |
1629 | } | |
1630 | ||
1631 | error = CC_REE_FIPS_ERROR_AESGCM_PUT; | |
1632 | break; | |
1633 | } | |
1634 | } | |
1635 | ||
1636 | /* compare actual mac result to expected */ | |
1637 | if (memcmp(virt_ctx->mac_res, gcmData->macResOut, gcmData->tagSize) != 0) | |
1638 | { | |
1639 | FIPS_LOG("mac_res comparison error %d - mac_size=%d \n", i, gcmData->tagSize); | |
1640 | FIPS_LOG(" i expected received \n"); | |
1641 | FIPS_LOG(" i 0x%08x 0x%08x \n", (size_t)gcmData->macResOut, (size_t)virt_ctx->mac_res); | |
1642 | for (i = 0; i < gcmData->tagSize; ++i) | |
1643 | { | |
1644 | FIPS_LOG(" %d 0x%02x 0x%02x \n", i, gcmData->macResOut[i], virt_ctx->mac_res[i]); | |
1645 | } | |
1646 | ||
1647 | error = CC_REE_FIPS_ERROR_AESGCM_PUT; | |
1648 | break; | |
1649 | } | |
1650 | } | |
1651 | return error; | |
1652 | } | |
1653 | ||
1654 | ||
1655 | size_t ssi_fips_max_mem_alloc_size(void) | |
1656 | { | |
1657 | FIPS_DBG("sizeof(struct fips_cipher_ctx) %d \n", sizeof(struct fips_cipher_ctx)); | |
1658 | FIPS_DBG("sizeof(struct fips_cmac_ctx) %d \n", sizeof(struct fips_cmac_ctx)); | |
1659 | FIPS_DBG("sizeof(struct fips_hash_ctx) %d \n", sizeof(struct fips_hash_ctx)); | |
1660 | FIPS_DBG("sizeof(struct fips_hmac_ctx) %d \n", sizeof(struct fips_hmac_ctx)); | |
1661 | FIPS_DBG("sizeof(struct fips_ccm_ctx) %d \n", sizeof(struct fips_ccm_ctx)); | |
1662 | FIPS_DBG("sizeof(struct fips_gcm_ctx) %d \n", sizeof(struct fips_gcm_ctx)); | |
1663 | ||
1664 | return sizeof(fips_ctx); | |
1665 | } | |
1666 |