1 /* 2 * Copyright (C) 2015-2018 Alibaba Group Holding Limited 3 */ 4 #ifndef INFRA_AES_H 5 #define INFRA_AES_H 6 7 #ifdef __cplusplus 8 extern "C" { 9 #endif 10 11 #if defined(INFRA_AES_BUILDIN) 12 #include "linkkit/infra/infra_aes_config.h" 13 #endif 14 15 #include <stddef.h> 16 #include <stdint.h> 17 18 #include "linkkit/infra/infra_compat.h" 19 20 /* padlock.c and aesni.c rely on these values! */ 21 #define INFRA_AES_ENCRYPT 1 22 #define INFRA_AES_DECRYPT 0 23 24 #define INFRA_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */ 25 #define INFRA_ERR_AES_INVALID_INPUT_LENGTH \ 26 -0x0022 /**< Invalid data input length. */ 27 28 #if (defined(__ARMCC_VERSION) || defined(_MSC_VER)) && !defined(inline) && \ 29 !defined(__cplusplus) 30 #define inline __inline 31 #endif 32 33 /** 34 * \brief AES context structure 35 * 36 * \note buf is able to hold 32 extra bytes, which can be used: 37 * - for alignment purposes if VIA padlock is used, and/or 38 * - to simplify key expansion in the 256-bit case by 39 * generating an extra round key 40 */ 41 typedef struct { 42 int nr; /*!< number of rounds */ 43 uint32_t *rk; /*!< AES round keys */ 44 uint32_t buf[68]; /*!< unaligned data */ 45 } infra_aes_context; 46 47 /** 48 * \brief Initialize AES context 49 * 50 * \param ctx AES context to be initialized 51 */ 52 53 void infra_aes_init(infra_aes_context *ctx); 54 55 /** 56 * \brief Clear AES context 57 * 58 * \param ctx AES context to be cleared 59 */ 60 void infra_aes_free(infra_aes_context *ctx); 61 62 /** 63 * \brief AES key schedule (encryption) 64 * 65 * \param ctx AES context to be initialized 66 * \param key encryption key 67 * \param keybits must be 128, 192 or 256 68 * 69 * \return 0 if successful, or INFRA_ERR_AES_INVALID_KEY_LENGTH 70 */ 71 int infra_aes_setkey_enc(infra_aes_context *ctx, const unsigned char *key, 72 unsigned int keybits); 73 74 /** 75 * \brief AES key schedule (decryption) 76 * 77 * \param ctx AES context to be initialized 78 * \param key decryption key 79 * \param keybits must be 128, 192 or 256 80 * 81 * \return 0 if successful, or INFRA_ERR_AES_INVALID_KEY_LENGTH 82 */ 83 int infra_aes_setkey_dec(infra_aes_context *ctx, const unsigned char *key, 84 unsigned int keybits); 85 86 /** 87 * \brief AES-ECB block encryption/decryption 88 * 89 * \param ctx AES context 90 * \param mode INFRA_AES_ENCRYPT or INFRA_AES_DECRYPT 91 * \param input 16-byte input block 92 * \param output 16-byte output block 93 * 94 * \return 0 if successful 95 */ 96 int infra_aes_crypt_ecb(infra_aes_context *ctx, int mode, 97 const unsigned char input[16], 98 unsigned char output[16]); 99 100 #if defined(INFRA_CIPHER_MODE_CBC) 101 /** 102 * \brief AES-CBC buffer encryption/decryption 103 * Length should be a multiple of the block 104 * size (16 bytes) 105 * 106 * \note Upon exit, the content of the IV is updated so that you can 107 * call the function same function again on the following 108 * block(s) of data and get the same result as if it was 109 * encrypted in one call. This allows a "streaming" usage. 110 * If on the other hand you need to retain the contents of the 111 * IV, you should either save it manually or use the cipher 112 * module instead. 113 * 114 * \param ctx AES context 115 * \param mode INFRA_AES_ENCRYPT or INFRA_AES_DECRYPT 116 * \param length length of the input data 117 * \param iv initialization vector (updated after use) 118 * \param input buffer holding the input data 119 * \param output buffer holding the output data 120 * 121 * \return 0 if successful, or INFRA_ERR_AES_INVALID_INPUT_LENGTH 122 */ 123 int infra_aes_crypt_cbc(infra_aes_context *ctx, int mode, size_t length, 124 unsigned char iv[16], const unsigned char *input, 125 unsigned char *output); 126 #endif /* INFRA_CIPHER_MODE_CBC */ 127 128 #if defined(INFRA_CIPHER_MODE_CFB) 129 /** 130 * \brief AES-CFB128 buffer encryption/decryption. 131 * 132 * Note: Due to the nature of CFB you should use the same key schedule for 133 * both encryption and decryption. So a context initialized with 134 * infra_aes_setkey_enc() for both INFRA_AES_ENCRYPT and INFRA_AES_DECRYPT. 135 * 136 * \note Upon exit, the content of the IV is updated so that you can 137 * call the function same function again on the following 138 * block(s) of data and get the same result as if it was 139 * encrypted in one call. This allows a "streaming" usage. 140 * If on the other hand you need to retain the contents of the 141 * IV, you should either save it manually or use the cipher 142 * module instead. 143 * 144 * \param ctx AES context 145 * \param mode INFRA_AES_ENCRYPT or INFRA_AES_DECRYPT 146 * \param length length of the input data 147 * \param iv_off offset in IV (updated after use) 148 * \param iv initialization vector (updated after use) 149 * \param input buffer holding the input data 150 * \param output buffer holding the output data 151 * 152 * \return 0 if successful 153 */ 154 int infra_aes_crypt_cfb128(infra_aes_context *ctx, int mode, size_t length, 155 size_t *iv_off, unsigned char iv[16], 156 const unsigned char *input, unsigned char *output); 157 158 /** 159 * \brief AES-CFB8 buffer encryption/decryption. 160 * 161 * Note: Due to the nature of CFB you should use the same key schedule for 162 * both encryption and decryption. So a context initialized with 163 * infra_aes_setkey_enc() for both INFRA_AES_ENCRYPT and INFRA_AES_DECRYPT. 164 * 165 * \note Upon exit, the content of the IV is updated so that you can 166 * call the function same function again on the following 167 * block(s) of data and get the same result as if it was 168 * encrypted in one call. This allows a "streaming" usage. 169 * If on the other hand you need to retain the contents of the 170 * IV, you should either save it manually or use the cipher 171 * module instead. 172 * 173 * \param ctx AES context 174 * \param mode INFRA_AES_ENCRYPT or INFRA_AES_DECRYPT 175 * \param length length of the input data 176 * \param iv initialization vector (updated after use) 177 * \param input buffer holding the input data 178 * \param output buffer holding the output data 179 * 180 * \return 0 if successful 181 */ 182 int infra_aes_crypt_cfb8(infra_aes_context *ctx, int mode, size_t length, 183 unsigned char iv[16], const unsigned char *input, 184 unsigned char *output); 185 #endif /*INFRA_CIPHER_MODE_CFB */ 186 187 #if defined(INFRA_CIPHER_MODE_CTR) 188 /** 189 * \brief AES-CTR buffer encryption/decryption 190 * 191 * Warning: You have to keep the maximum use of your counter in mind! 192 * 193 * Note: Due to the nature of CTR you should use the same key schedule for 194 * both encryption and decryption. So a context initialized with 195 * infra_aes_setkey_enc() for both INFRA_AES_ENCRYPT and INFRA_AES_DECRYPT. 196 * 197 * \param ctx AES context 198 * \param length The length of the data 199 * \param nc_off The offset in the current stream_block (for resuming 200 * within current cipher stream). The offset pointer to 201 * should be 0 at the start of a stream. 202 * \param nonce_counter The 128-bit nonce and counter. 203 * \param stream_block The saved stream-block for resuming. Is overwritten 204 * by the function. 205 * \param input The input data stream 206 * \param output The output data stream 207 * 208 * \return 0 if successful 209 */ 210 int infra_aes_crypt_ctr(infra_aes_context *ctx, size_t length, size_t *nc_off, 211 unsigned char nonce_counter[16], 212 unsigned char stream_block[16], 213 const unsigned char *input, unsigned char *output); 214 #endif /* INFRA_CIPHER_MODE_CTR */ 215 216 /** 217 * \brief Internal AES block encryption function 218 * (Only exposed to allow overriding it, 219 * see INFRA_AES_ENCRYPT_ALT) 220 * 221 * \param ctx AES context 222 * \param input Plaintext block 223 * \param output Output (ciphertext) block 224 * 225 * \return 0 if successful 226 */ 227 int infra_internal_aes_encrypt(infra_aes_context *ctx, 228 const unsigned char input[16], 229 unsigned char output[16]); 230 231 /** 232 * \brief Internal AES block decryption function 233 * (Only exposed to allow overriding it, 234 * see INFRA_AES_DECRYPT_ALT) 235 * 236 * \param ctx AES context 237 * \param input Ciphertext block 238 * \param output Output (plaintext) block 239 * 240 * \return 0 if successful 241 */ 242 int infra_internal_aes_decrypt(infra_aes_context *ctx, 243 const unsigned char input[16], 244 unsigned char output[16]); 245 246 /** 247 * \brief Checkup routine 248 * 249 * \return 0 if successful, or 1 if the test failed 250 */ 251 int infra_aes_self_test(int verbose); 252 253 typedef infra_aes_context mbedtls_aes_context; 254 255 #if !defined(INFRA_AES_BUILDIN) 256 void mbedtls_aes_free(mbedtls_aes_context *ctx); 257 void mbedtls_aes_init(mbedtls_aes_context *ctx); 258 int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key, 259 unsigned int keybits); 260 int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key, 261 unsigned int keybits); 262 int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx, int mode, size_t length, 263 unsigned char iv[16], const unsigned char *input, 264 unsigned char *output); 265 int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx, int mode, size_t length, 266 size_t *iv_off, unsigned char iv[16], 267 const unsigned char *input, unsigned char *output); 268 269 #define MBEDTLS_AES_DECRYPT INFRA_AES_DECRYPT 270 #define MBEDTLS_AES_ENCRYPT INFRA_AES_ENCRYPT 271 #endif 272 273 #define AES_BLOCK_SIZE (16) 274 275 p_Aes128_t infra_aes128_init(const uint8_t *key, const uint8_t *iv, 276 AES_DIR_t dir); 277 278 int infra_aes128_destroy(p_Aes128_t aes); 279 280 int infra_aes128_cbc_decrypt(p_Aes128_t aes, const void *src, size_t blockNum, 281 void *dst); 282 283 int infra_aes128_cfb_decrypt(p_Aes128_t aes, const void *src, size_t length, 284 void *dst); 285 286 int infra_aes128_cfb_encrypt(p_Aes128_t aes, const void *src, size_t length, 287 void *dst); 288 289 int infra_aes128_cbc_encrypt(p_Aes128_t aes, const void *src, size_t blockNum, 290 void *dst); 291 292 #ifdef __cplusplus 293 } 294 #endif 295 #endif /* aes.h */ 296