#include "common.h" #if defined(MBEDTLS_AES_C) #if defined(MBEDTLS_AES_ALT) #include #include "aes_alt.h" #include "mbedtls/aes.h" #include "mbedtls/error.h" void mbedtls_aes_init(mbedtls_aes_context *ctx) { memset(ctx, 0, sizeof(mbedtls_aes_context)); ctx->hw = (struct sysaes_dev *)dev_get(HG_HWAES0_DEVID); } void mbedtls_aes_free(mbedtls_aes_context *ctx) { if (ctx == NULL) { return; } mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context)); } #if defined(MBEDTLS_CIPHER_MODE_XTS) void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx) { mbedtls_aes_init(&ctx->crypt); mbedtls_aes_init(&ctx->tweak); } void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx) { if (ctx == NULL) { return; } mbedtls_aes_free(&ctx->crypt); mbedtls_aes_free(&ctx->tweak); } #endif /* MBEDTLS_CIPHER_MODE_XTS */ /* * AES key schedule (encryption) */ int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits) { switch (keybits) { case 128: ctx->para.key_len = AES_KEY_LEN_BIT_128; break; case 192: ctx->para.key_len = AES_KEY_LEN_BIT_192; break; case 256: ctx->para.key_len = AES_KEY_LEN_BIT_256; break; default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH; } memcpy(ctx->para.key, key, keybits/8); return 0; } /* * AES key schedule (decryption) */ int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits) { return mbedtls_aes_setkey_enc(ctx, key, keybits); } #if defined(MBEDTLS_CIPHER_MODE_XTS) static int mbedtls_aes_xts_decode_keys(const unsigned char *key, unsigned int keybits, const unsigned char **key1, unsigned int *key1bits, const unsigned char **key2, unsigned int *key2bits) { const unsigned int half_keybits = keybits / 2; const unsigned int half_keybytes = half_keybits / 8; switch (keybits) { case 256: break; case 512: break; default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH; } *key1bits = half_keybits; *key2bits = half_keybits; *key1 = &key[0]; *key2 = &key[half_keybytes]; return 0; } int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx, const unsigned char *key, unsigned int keybits) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; const unsigned char *key1, *key2; unsigned int key1bits, key2bits; ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits, &key2, &key2bits); if (ret != 0) { return ret; } /* Set the tweak key. Always set tweak key for the encryption mode. */ ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits); if (ret != 0) { return ret; } /* Set crypt key for encryption. */ return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits); } int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx, const unsigned char *key, unsigned int keybits) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; const unsigned char *key1, *key2; unsigned int key1bits, key2bits; ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits, &key2, &key2bits); if (ret != 0) { return ret; } /* Set the tweak key. Always set tweak key for encryption. */ ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits); if (ret != 0) { return ret; } /* Set crypt key for decryption. */ return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits); } #endif /* MBEDTLS_CIPHER_MODE_XTS */ /* * AES-ECB block encryption/decryption */ int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx, int mode, const unsigned char input[16], unsigned char output[16]) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) { return MBEDTLS_ERR_AES_BAD_INPUT_DATA; } if (input && output) { ctx->para.mode = AES_MODE_ECB; ctx->para.src = (uint8 *)input; ctx->para.dest = (uint8 *)output; ctx->para.aes_len = 16; // mbedtls默认ecb操作16字节 if (mode == MBEDTLS_AES_ENCRYPT) { ret = sysaes_encrypt(ctx->hw, &ctx->para); } else { ret = sysaes_decrypt(ctx->hw, &ctx->para); } } return ret; } #if defined(MBEDTLS_CIPHER_MODE_CBC) /* * AES-CBC buffer encryption/decryption */ int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx, int mode, size_t length, unsigned char iv[16], const unsigned char *input, unsigned char *output) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; unsigned char temp[16]; if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) { return MBEDTLS_ERR_AES_BAD_INPUT_DATA; } if (length % 16) { return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH; } if (input && output && iv) { ctx->para.mode = AES_MODE_CBC; ctx->para.src = (uint8 *)input; ctx->para.dest = (uint8 *)output; ctx->para.aes_len = length; ctx->para.iv = iv; if (mode == MBEDTLS_AES_ENCRYPT) { ret = sysaes_encrypt(ctx->hw, &ctx->para); memcpy(iv, output, 16); // iv更新为加密后的output } else { memcpy(temp, input, 16); ret = sysaes_decrypt(ctx->hw, &ctx->para); memcpy(iv, temp, 16); // iv更新为解密前的input } } return ret; } #endif /* MBEDTLS_CIPHER_MODE_CBC */ #if defined(MBEDTLS_CIPHER_MODE_XTS) typedef unsigned char mbedtls_be128[16]; /* * GF(2^128) multiplication function * * This function multiplies a field element by x in the polynomial field * representation. It uses 64-bit word operations to gain speed but compensates * for machine endianness and hence works correctly on both big and little * endian machines. */ static void mbedtls_gf128mul_x_ble(unsigned char r[16], const unsigned char x[16]) { uint64_t a, b, ra, rb; a = MBEDTLS_GET_UINT64_LE(x, 0); b = MBEDTLS_GET_UINT64_LE(x, 8); ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3)); rb = (a >> 63) | (b << 1); MBEDTLS_PUT_UINT64_LE(ra, r, 0); MBEDTLS_PUT_UINT64_LE(rb, r, 8); } /* * AES-XTS buffer encryption/decryption */ int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx, int mode, size_t length, const unsigned char data_unit[16], const unsigned char *input, unsigned char *output) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; size_t blocks = length / 16; size_t leftover = length % 16; unsigned char tweak[16]; unsigned char prev_tweak[16]; unsigned char tmp[16]; if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) { return MBEDTLS_ERR_AES_BAD_INPUT_DATA; } /* Data units must be at least 16 bytes long. */ if (length < 16) { return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH; } /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */ if (length > (1 << 20) * 16) { return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH; } /* Compute the tweak. */ ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT, data_unit, tweak); if (ret != 0) { return ret; } while (blocks--) { if (leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0) { /* We are on the last block in a decrypt operation that has * leftover bytes, so we need to use the next tweak for this block, * and this tweak for the leftover bytes. Save the current tweak for * the leftovers and then update the current tweak for use on this, * the last full block. */ memcpy(prev_tweak, tweak, sizeof(tweak)); mbedtls_gf128mul_x_ble(tweak, tweak); } mbedtls_xor(tmp, input, tweak, 16); ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp); if (ret != 0) { return ret; } mbedtls_xor(output, tmp, tweak, 16); /* Update the tweak for the next block. */ mbedtls_gf128mul_x_ble(tweak, tweak); output += 16; input += 16; } if (leftover) { /* If we are on the leftover bytes in a decrypt operation, we need to * use the previous tweak for these bytes (as saved in prev_tweak). */ unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak; /* We are now on the final part of the data unit, which doesn't divide * evenly by 16. It's time for ciphertext stealing. */ size_t i; unsigned char *prev_output = output - 16; /* Copy ciphertext bytes from the previous block to our output for each * byte of ciphertext we won't steal. */ for (i = 0; i < leftover; i++) { output[i] = prev_output[i]; } /* Copy the remainder of the input for this final round. */ mbedtls_xor(tmp, input, t, leftover); /* Copy ciphertext bytes from the previous block for input in this * round. */ mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i); ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp); if (ret != 0) { return ret; } /* Write the result back to the previous block, overriding the previous * output we copied. */ mbedtls_xor(prev_output, tmp, t, 16); } return 0; } #endif /* MBEDTLS_CIPHER_MODE_XTS */ #if defined(MBEDTLS_CIPHER_MODE_CFB) /* * AES-CFB128 buffer encryption/decryption */ int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx, int mode, size_t length, size_t *iv_off, unsigned char iv[16], const unsigned char *input, unsigned char *output) { int c; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; size_t n; if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) { return MBEDTLS_ERR_AES_BAD_INPUT_DATA; } n = *iv_off; if (n > 15) { return MBEDTLS_ERR_AES_BAD_INPUT_DATA; } if (mode == MBEDTLS_AES_DECRYPT) { while (length--) { if (n == 0) { ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv); if (ret != 0) { goto exit; } } c = *input++; *output++ = (unsigned char) (c ^ iv[n]); iv[n] = (unsigned char) c; n = (n + 1) & 0x0F; } } else { while (length--) { if (n == 0) { ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv); if (ret != 0) { goto exit; } } iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++); n = (n + 1) & 0x0F; } } *iv_off = n; ret = 0; exit: return ret; } /* * AES-CFB8 buffer encryption/decryption */ int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx, int mode, size_t length, unsigned char iv[16], const unsigned char *input, unsigned char *output) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; unsigned char c; unsigned char ov[17]; if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) { return MBEDTLS_ERR_AES_BAD_INPUT_DATA; } while (length--) { memcpy(ov, iv, 16); ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv); if (ret != 0) { goto exit; } if (mode == MBEDTLS_AES_DECRYPT) { ov[16] = *input; } c = *output++ = (unsigned char) (iv[0] ^ *input++); if (mode == MBEDTLS_AES_ENCRYPT) { ov[16] = c; } memcpy(iv, ov + 1, 16); } ret = 0; exit: return ret; } #endif /* MBEDTLS_CIPHER_MODE_CFB */ #if defined(MBEDTLS_CIPHER_MODE_OFB) /* * AES-OFB (Output Feedback Mode) buffer encryption/decryption */ int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx, size_t length, size_t *iv_off, unsigned char iv[16], const unsigned char *input, unsigned char *output) { int ret = 0; size_t n; n = *iv_off; if (n > 15) { return MBEDTLS_ERR_AES_BAD_INPUT_DATA; } while (length--) { if (n == 0) { ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv); if (ret != 0) { goto exit; } } *output++ = *input++ ^ iv[n]; n = (n + 1) & 0x0F; } *iv_off = n; exit: return ret; } #endif /* MBEDTLS_CIPHER_MODE_OFB */ #if defined(MBEDTLS_CIPHER_MODE_CTR) /* * AES-CTR buffer encryption/decryption */ int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx, size_t length, size_t *nc_off, unsigned char nonce_counter[16], unsigned char stream_block[16], const unsigned char *input, unsigned char *output) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; unsigned char temp[16]; size_t n; // 硬件上其实并没有使用nc_off和stram_block参数 n = *nc_off; if (n > 0x0F) { return MBEDTLS_ERR_AES_BAD_INPUT_DATA; } if (input && output && nonce_counter) { ctx->para.mode = AES_MODE_CTR; ctx->para.src = (uint8 *)input; ctx->para.dest = (uint8 *)output; ctx->para.aes_len = length; // 硬件设计counter字节序反了,占用16bit,直接交换高2字节 // 👆驱动内部调整了 #if 0 memcpy(temp, nonce_counter, 14); temp[14] = nonce_counter[15]; temp[15] = nonce_counter[14]; #else memcpy(temp, nonce_counter, 16); #endif ctx->para.iv = temp; ret = sysaes_encrypt(ctx->hw, &ctx->para); } return ret; } #endif /* MBEDTLS_CIPHER_MODE_CTR */ #endif /* MBEDTLS_AES_ALT */ #endif /* MBEDTLS_AES_C */