Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 | /* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (c) 2011 The Chromium OS Authors. * (C) Copyright 2010 - 2011 NVIDIA Corporation <www.nvidia.com> */ #ifndef _AES_REF_H_ #define _AES_REF_H_ #include <errno.h> #ifdef USE_HOSTCC /* Define compat stuff for use in fw_* tools. */ typedef unsigned char u8; typedef unsigned int u32; #define debug(...) do {} while (0) #endif /* * AES encryption library, with small code size, supporting only 128-bit AES * * AES is a stream cipher which works a block at a time, with each block * in this case being AES_BLOCK_LENGTH bytes. */ enum { AES_STATECOLS = 4, /* columns in the state & expanded key */ AES128_KEYCOLS = 4, /* columns in a key for aes128 */ AES192_KEYCOLS = 6, /* columns in a key for aes128 */ AES256_KEYCOLS = 8, /* columns in a key for aes128 */ AES128_ROUNDS = 10, /* rounds in encryption for aes128 */ AES192_ROUNDS = 12, /* rounds in encryption for aes192 */ AES256_ROUNDS = 14, /* rounds in encryption for aes256 */ AES128_KEY_LENGTH = 128 / 8, AES192_KEY_LENGTH = 192 / 8, AES256_KEY_LENGTH = 256 / 8, AES128_EXPAND_KEY_LENGTH = 4 * AES_STATECOLS * (AES128_ROUNDS + 1), AES192_EXPAND_KEY_LENGTH = 4 * AES_STATECOLS * (AES192_ROUNDS + 1), AES256_EXPAND_KEY_LENGTH = 4 * AES_STATECOLS * (AES256_ROUNDS + 1), AES_BLOCK_LENGTH = 128 / 8, }; /** * aes_expand_key() - Expand the AES key * * Expand a key into a key schedule, which is then used for the other * operations. * * @key Key (not modified) * @key_size Size of the key (in bits) * @expkey Buffer to place expanded key, AES_EXPAND_KEY_LENGTH */ void aes_expand_key(const u8 *key, u32 key_size, u8 *expkey); /** * aes_encrypt() - Encrypt single block of data with AES 128 * * @key_size Size of the aes key (in bits) * @in Input data (not modified) * @expkey Expanded key to use for encryption (from aes_expand_key(), not modified) * @out Output data */ void aes_encrypt(u32 key_size, const u8 *in, const u8 *expkey, u8 *out); /** * aes_decrypt() - Decrypt single block of data with AES 128 * * @key_size Size of the aes key (in bits) * @in Input data (not modified) * @expkey Expanded key to use for decryption (from aes_expand_key(), not modified) * @out Output data */ void aes_decrypt(u32 key_size, const u8 *in, const u8 *expkey, u8 *out); /** * Apply chain data to the destination using EOR * * Each array is of length AES_BLOCK_LENGTH. * * @cbc_chain_data Chain data (not modified) * @src Source data (not modified) * @dst Destination data, which is modified here */ void aes_apply_cbc_chain_data(const u8 *cbc_chain_data, const u8 *src, u8 *dst); /** * aes_cbc_encrypt_blocks() - Encrypt multiple blocks of data with AES CBC. * * @key_size Size of the aes key (in bits) * @key_exp Expanded key to use (not modified) * @iv Initialization vector (not modified) * @src Source data to encrypt (not modified) * @dst Destination buffer * @num_aes_blocks Number of AES blocks to encrypt */ void aes_cbc_encrypt_blocks(u32 key_size, const u8 *key_exp, const u8 *iv, const u8 *src, u8 *dst, u32 num_aes_blocks); /** * Decrypt multiple blocks of data with AES CBC. * * @key_size Size of the aes key (in bits) * @key_exp Expanded key to use (not modified) * @iv Initialization vector (not modified) * @src Source data to decrypt (not modified) * @dst Destination buffer * @num_aes_blocks Number of AES blocks to decrypt */ void aes_cbc_decrypt_blocks(u32 key_size, const u8 *key_exp, const u8 *iv, const u8 *src, u8 *dst, u32 num_aes_blocks); /* An AES block filled with zeros */ static const u8 AES_ZERO_BLOCK[AES_BLOCK_LENGTH] = { 0 }; struct udevice; /** * struct struct aes_ops - Driver model for AES related operations * * The uclass interface is implemented by AES crypto devices which use driver model. * * Some AES crypto devices use key slots to store the key for the encrypt/decrypt * operations, while others may simply pass the key on each operation. * * In case the device does not implement hardware slots, driver can emulate or simply * store one active key slot at 0 in the driver state and pass it on each underlying * hw calls for AES operations. * * Note that some devices like Tegra AES engine may contain preloaded keys by bootrom, * thus in those cases the set_key_for_key_slot() may be skipped. * * Sequence for a series of AES CBC encryption, one decryption and a CMAC hash example * with 128bits key at slot 0 would be as follow: * * set_key_for_key_slot(DEV, 128, KEY, 0); * select_key_slot(DEV, 128, 0); * aes_cbc_encrypt(DEV, IV1, SRC1, DST1, LEN1); * aes_cbc_encrypt(DEV, IV2, SRC2, DST2, LEN2); * aes_cbc_decrypt(DEV, IV3, SRC3, DST3, LEN3); */ struct aes_ops { /** * available_key_slots() - How many key slots this AES device has * * @dev The AES udevice * @return Available slots to use, 0 for none */ int (*available_key_slots)(struct udevice *dev); /** * select_key_slot() - Selects the AES key slot to use for following operations * * @dev The AES udevice * @key_size Size of the aes key (in bits) * @slot The key slot to set as selected * @return 0 on success, negative value on failure */ int (*select_key_slot)(struct udevice *dev, u32 key_size, u8 slot); /** * set_key_for_key_slot() - Sets the AES key to use for specified key slot * * @dev The AES udevice * @key_size Size of the aes key (in bits) * @key An AES key to set * @slot The slot to load the key at * @return 0 on success, negative value on failure */ int (*set_key_for_key_slot)(struct udevice *dev, u32 key_size, u8 *key, u8 slot); /** * aes_ecb_encrypt() - Encrypt multiple blocks of data with AES ECB. * * @dev The AES udevice * @src Source data of length 'num_aes_blocks' blocks * @dst Destination data of length 'num_aes_blocks' blocks * @num_aes_blocks Number of AES blocks to encrypt/decrypt * @return 0 on success, negative value on failure */ int (*aes_ecb_encrypt)(struct udevice *dev, u8 *src, u8 *dst, u32 num_aes_blocks); /** * aes_ecb_decrypt() - Decrypt multiple blocks of data with AES ECB. * * @dev The AES udevice * @src Source data of length 'num_aes_blocks' blocks * @dst Destination data of length 'num_aes_blocks' blocks * @num_aes_blocks Number of AES blocks to encrypt/decrypt * @return 0 on success, negative value on failure */ int (*aes_ecb_decrypt)(struct udevice *dev, u8 *src, u8 *dst, u32 num_aes_blocks); /** * aes_cbc_encrypt() - Encrypt multiple blocks of data with AES CBC. * * @dev The AES udevice * @iv Initialization vector * @src Source data of length 'num_aes_blocks' blocks * @dst Destination data of length 'num_aes_blocks' blocks * @num_aes_blocks Number of AES blocks to encrypt/decrypt * @return 0 on success, negative value on failure */ int (*aes_cbc_encrypt)(struct udevice *dev, u8 *iv, u8 *src, u8 *dst, u32 num_aes_blocks); /** * aes_cbc_decrypt() - Decrypt multiple blocks of data with AES CBC. * * @dev The AES udevice * @iv Initialization vector * @src Source data of length 'num_aes_blocks' blocks * @dst Destination data of length 'num_aes_blocks' blocks * @num_aes_blocks Number of AES blocks to encrypt/decrypt * @return 0 on success, negative value on failure */ int (*aes_cbc_decrypt)(struct udevice *dev, u8 *iv, u8 *src, u8 *dst, u32 num_aes_blocks); }; #define aes_get_ops(dev) ((struct aes_ops *)(dev)->driver->ops) #if CONFIG_IS_ENABLED(DM_AES) /** * dm_aes_get_available_key_slots - How many key slots this AES device has * * @dev The AES udevice * Return: Available slots to use, 0 for none, -ve on failure */ int dm_aes_get_available_key_slots(struct udevice *dev); /** * dm_aes_select_key_slot - Selects the AES key slot to use for following operations * * @dev The AES udevice * @key_size Size of the aes key (in bits) * @slot The key slot to set as selected * Return: 0 on success, -ve on failure */ int dm_aes_select_key_slot(struct udevice *dev, u32 key_size, u8 slot); /** * dm_aes_set_key_for_key_slot - Sets the AES key to use for specified key slot * * @dev The AES udevice * @key_size Size of the aes key (in bits) * @key An AES key to set * @slot The slot to load the key at * Return: 0 on success, negative value on failure */ int dm_aes_set_key_for_key_slot(struct udevice *dev, u32 key_size, u8 *key, u8 slot); /** * dm_aes_ecb_encrypt - Encrypt multiple blocks of data with AES ECB. * * @dev The AES udevice * @src Source data of length 'num_aes_blocks' blocks * @dst Destination data of length 'num_aes_blocks' blocks * @num_aes_blocks Number of AES blocks to encrypt/decrypt * Return: 0 on success, negative value on failure */ int dm_aes_ecb_encrypt(struct udevice *dev, u8 *src, u8 *dst, u32 num_aes_blocks); /** * dm_aes_ecb_decrypt - Decrypt multiple blocks of data with AES ECB. * * @dev The AES udevice * @src Source data of length 'num_aes_blocks' blocks * @dst Destination data of length 'num_aes_blocks' blocks * @num_aes_blocks Number of AES blocks to encrypt/decrypt * Return: 0 on success, negative value on failure */ int dm_aes_ecb_decrypt(struct udevice *dev, u8 *src, u8 *dst, u32 num_aes_blocks); /** * dm_aes_cbc_encrypt - Encrypt multiple blocks of data with AES CBC. * * @dev The AES udevice * @iv Initialization vector * @src Source data of length 'num_aes_blocks' blocks * @dst Destination data of length 'num_aes_blocks' blocks * @num_aes_blocks Number of AES blocks to encrypt/decrypt * Return: 0 on success, negative value on failure */ int dm_aes_cbc_encrypt(struct udevice *dev, u8 *iv, u8 *src, u8 *dst, u32 num_aes_blocks); /** * dm_aes_cbc_decrypt - Decrypt multiple blocks of data with AES CBC. * * @dev The AES udevice * @iv Initialization vector * @src Source data of length 'num_aes_blocks' blocks * @dst Destination data of length 'num_aes_blocks' blocks * @num_aes_blocks Number of AES blocks to encrypt/decrypt * Return: 0 on success, negative value on failure */ int dm_aes_cbc_decrypt(struct udevice *dev, u8 *iv, u8 *src, u8 *dst, u32 num_aes_blocks); /** * dm_aes_cmac - Hashes the input data with AES-CMAC, putting the result into dst. * The key slot must be selected already. * * @dev The AES udevice * @key_size Size of the aes key (in bits) * @src Source data of length 'num_aes_blocks' blocks * @dst Destination for hash result * @num_aes_blocks Number of AES blocks to encrypt * Return: 0 on success, negative value on failure. */ int dm_aes_cmac(struct udevice *dev, u8 *src, u8 *dst, u32 num_aes_blocks); #else static inline int dm_aes_get_available_key_slots(struct udevice *dev) { return -ENOSYS; } static inline int dm_aes_select_key_slot(struct udevice *dev, u32 key_size, u8 slot) { return -ENOSYS; } static inline int dm_aes_set_key_for_key_slot(struct udevice *dev, u32 key_size, u8 *key, u8 slot) { return -ENOSYS; } static inline int dm_aes_ecb_encrypt(struct udevice *dev, u8 *src, u8 *dst, u32 num_aes_blocks) { return -ENOSYS; } static inline int dm_aes_ecb_decrypt(struct udevice *dev, u8 *src, u8 *dst, u32 num_aes_blocks) { return -ENOSYS; } static inline int dm_aes_cbc_encrypt(struct udevice *dev, u8 *iv, u8 *src, u8 *dst, u32 num_aes_blocks) { return -ENOSYS; } static inline int dm_aes_cbc_decrypt(struct udevice *dev, u8 *iv, u8 *src, u8 *dst, u32 num_aes_blocks) { return -ENOSYS; } static inline int dm_aes_cmac(struct udevice *dev, u8 *src, u8 *dst, u32 num_aes_blocks) { return -ENOSYS; } #endif /* CONFIG_DM_AES */ #endif /* _AES_REF_H_ */ |