rel_1.6.0 init

This commit is contained in:
guocheng.kgc 2020-06-18 20:06:52 +08:00 committed by shengdong.dsd
commit 27b3e2883d
19359 changed files with 8093121 additions and 0 deletions

View file

@ -0,0 +1,2 @@
Unless specifically indicated otherwise in a file, files are licensed
under the Apache 2.0 license, as can be found in: apache-2.0.txt

View file

@ -0,0 +1,17 @@
Alicrypto V1.0.0
add support AES pkcs5 padding
Alicrypto V1.0.1
fix aes ecb process bugs
Alicrypto V1.0.2
support IAR
Alicrypto V1.0.3
fix aes bugs(ecb/cbc/ctr nopad mode, finsh can input NULL data), fix WhiteScan bugs
Alicrypto V1.0.4
remove md func in hmac/rsa
Alicrypto V1.0.5
support aes cfb8/128

View file

@ -0,0 +1,85 @@
NAME := alicrypto
ALICRYPTO_TEST := no
ifneq (,$(BINS))
ifeq ($(MBEDTLS_SHARE),1)
$(NAME)_TYPE := framework&kernel
else
$(NAME)_TYPE := kernel
endif
endif
$(NAME)_INCLUDES += ./mbedtls/include/mbedtls
$(NAME)_INCLUDES += ./libalicrypto/mbed/inc
$(NAME)_INCLUDES += ./libalicrypto/sw
GLOBAL_INCLUDES += ./libalicrypto/inc
$(NAME)_CFLAGS += -DCONFIG_CRYPT_MBED=1 -DCONFIG_DBG_CRYPT=1
GLOBAL_DEFINES += CONFIG_ALICRYPTO
ifeq ($(COMPILER),)
$(NAME)_CFLAGS += -W -Wdeclaration-after-statement
endif
ifneq (, $(findstring cb2201, $(BUILD_STRING)))
$(NAME)_INCLUDES += ./csky/cb2201
$(NAME)_SOURCES += \
./csky/ch2201/aes.c \
./libalicrypto/mbed/hash/hash.c \
./csky/ch2201/rsa.c \
./libalicrypto/mbed/mac/hmac.c \
./csky/ch2201/rand.c \
./libalicrypto/ali_crypto.c
else
$(NAME)_SOURCES += \
./libalicrypto/mbed/cipher/aes.c \
./libalicrypto/mbed/hash/hash.c \
./libalicrypto/mbed/asym/rsa.c \
./libalicrypto/mbed/mac/hmac.c \
./libalicrypto/sw/ali_crypto_rand.c \
./libalicrypto/ali_crypto.c
endif
$(NAME)_CFLAGS += -D_FILE_OFFSET_BITS=64
$(NAME)_INCLUDES += ./mbedtls/include
$(NAME)_SOURCES += \
./mbedtls/library/aes.c
$(NAME)_SOURCES += \
./mbedtls/library/md5.c \
./mbedtls/library/sha1.c \
./mbedtls/library/sha256.c
$(NAME)_SOURCES += \
./mbedtls/library/hash_wrap.c \
./mbedtls/library/bignum.c \
./mbedtls/library/oid.c \
./mbedtls/library/rsa.c \
./mbedtls/library/threading.c \
./mbedtls/library/mbedtls_alt.c \
./mbedtls/library/asn1parse.c \
$(NAME)_SOURCES += \
./mbedtls/library/hmac.c \
ifeq ($(ALICRYPTO_TEST), yes)
$(NAME)_INCLUDES += ./libalicrypto/test/inc
$(NAME)_SOURCES += \
./libalicrypto/test/ali_crypto_test.c \
./libalicrypto/test/ali_crypto_test_comm.c \
./libalicrypto/test/ali_crypto_test_aes.c \
./libalicrypto/test/ali_crypto_test_hash.c \
./libalicrypto/test/ali_crypto_test_rand.c \
./libalicrypto/test/ali_crypto_test_rsa.c \
./libalicrypto/test/ali_crypto_test_hmac.c \
endif

View file

@ -0,0 +1,354 @@
/**
* Copyright (C) 2017 The YunOS Project. All rights reserved.
*/
#include "mbed_crypto.h"
#include "ali_crypto.h"
#include "drv_tee.h"
static uint8_t key_copy[32];
static uint32_t keylen_copy;
ali_crypto_result ali_aes_get_ctx_size(aes_type_t type, size_t *size)
{
if (size == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG, "aes_get_ctx_size: bad input!\n");
}
switch (type) {
case AES_ECB:
case AES_CBC:
case AES_CTR:
#if defined(MBEDTLS_CIPHER_MODE_CFB)
case AES_CFB8:
case AES_CFB128:
#endif
break;
case AES_CTS:
case AES_XTS:
PRINT_RET(ALI_CRYPTO_NOSUPPORT,
"ali_aes_init: invalid aes type(%d)\n", type);
default:
PRINT_RET(ALI_CRYPTO_INVALID_TYPE,
"ali_aes_init: invalid aes type(%d)\n", type);
}
*size = sizeof(aes_ctx_t);
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_aes_init(aes_type_t type, bool is_enc,
const uint8_t *key1, const uint8_t *key2,
size_t keybytes, const uint8_t *iv,
void *context)
{
aes_ctx_t *aes_ctx;
(void)key2;
if (key1 == NULL || context == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG, "ali_aes_init: bad input args!\n");
}
if (keybytes != 16 && keybytes != 24 && keybytes != 32) {
PRINT_RET(ALI_CRYPTO_LENGTH_ERR, "ali_aes_init: bad key lenth(%d)\n",
(int)keybytes);
}
aes_ctx = (aes_ctx_t *)context;
if ((IS_VALID_CTX_MAGIC(aes_ctx->magic) &&
aes_ctx->status != CRYPTO_STATUS_FINISHED) &&
aes_ctx->status != CRYPTO_STATUS_CLEAN) {
PRINT_RET(ALI_CRYPTO_ERR_STATE, "ali_aes_init: bad status(%d)\n",
(int)aes_ctx->status);
}
switch (type) {
case AES_ECB:
break;
case AES_CBC: {
if (iv == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG,
"ali_aes_init: cbc iv is null\n");
}
OSA_memcpy(aes_ctx->iv, iv, 16);
break;
}
case AES_CTR: {
if (iv == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG,
"ali_aes_init: ctr iv is null\n");
}
OSA_memcpy(aes_ctx->iv, iv, 16);
break;
}
#if defined(MBEDTLS_CIPHER_MODE_CFB)
case AES_CFB8:
case AES_CFB128: {
if (iv == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG,
"ali_aes_init: cfb iv is null\n");
}
OSA_memcpy(aes_ctx->iv, iv, 16);
break;
}
#endif
case AES_CTS:
case AES_XTS:
PRINT_RET(ALI_CRYPTO_NOSUPPORT,
"ali_aes_init: not support aes type(%d)\n", type);
break;
default:
PRINT_RET(ALI_CRYPTO_INVALID_TYPE,
"ali_aes_init: invalid aes type(%d)\n", type);
}
// mbedtls_aes_init(&(aes_ctx->ctx));
aes_ctx->is_enc = is_enc;
OSA_memcpy(key_copy, key1, keybytes);
keylen_copy = keybytes;
aes_ctx->offset = 0;
aes_ctx->type = type;
aes_ctx->status = CRYPTO_STATUS_INITIALIZED;
INIT_CTX_MAGIC(aes_ctx->magic);
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_aes_process(const uint8_t *src, uint8_t *dst, size_t size,
void *context)
{
int ret = ALI_CRYPTO_ERROR;
aes_ctx_t *aes_ctx;
if (context == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_CONTEXT, "ali_aes_process: bad ctx!\n");
}
if (src == NULL || dst == NULL || size == 0) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG, "ali_aes_process: bad args!\n");
}
aes_ctx = (aes_ctx_t *)context;
if (!IS_VALID_CTX_MAGIC(aes_ctx->magic)) {
PRINT_RET(ALI_CRYPTO_INVALID_CONTEXT, "ali_aes_process: bad magic!\n");
}
if ((aes_ctx->status != CRYPTO_STATUS_INITIALIZED) &&
(aes_ctx->status != CRYPTO_STATUS_PROCESSING)) {
PRINT_RET(ALI_CRYPTO_ERR_STATE, "ali_aes_update: bad status(%d)\n",
(int)aes_ctx->status);
}
switch (aes_ctx->type) {
/* FIXME, limitation, size must be block size aigned */
case AES_ECB: {
size_t cur_len = 0;
if (size % AES_BLOCK_SIZE != 0) {
PRINT_RET(ALI_CRYPTO_LENGTH_ERR,
"ali_aes_process: invalid size(%d)\n", (int)size);
}
while (cur_len < size) {
if (aes_ctx->is_enc) {
ret = csi_tee_aes_encrypt_ecb(src + cur_len, AES_BLOCK_SIZE,
key_copy, keylen_copy,
dst + cur_len);
} else {
ret = csi_tee_aes_decrypt_ecb(src + cur_len, AES_BLOCK_SIZE,
key_copy, keylen_copy,
dst + cur_len);
}
if (ret != 0) {
printf("aes engine fail \n");
}
cur_len += AES_BLOCK_SIZE;
}
break;
}
case AES_CBC: {
if (size % AES_BLOCK_SIZE != 0) {
PRINT_RET(ALI_CRYPTO_LENGTH_ERR,
"ali_aes_process: invalid size(%d)\n", (int)size);
}
if (aes_ctx->is_enc) {
ret = csi_tee_aes_encrypt_cbc(src, size, key_copy, keylen_copy,
aes_ctx->iv, dst);
} else {
ret = csi_tee_aes_decrypt_cbc(src, size, key_copy, keylen_copy,
aes_ctx->iv, dst);
}
#if 0 /* mbedtls have copy it */
if (ret == ALI_CRYPTO_SUCCESS) {
OSA_memcpy(aes_ctx->iv, src - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
}
#endif
break;
}
case AES_CTR: {
break;
}
#if defined(MBEDTLS_CIPHER_MODE_CFB)
case AES_CFB8: {
break;
}
case AES_CFB128: {
break;
}
#endif
case AES_CTS:
case AES_XTS:
default:
PRINT_RET(ALI_CRYPTO_NOSUPPORT,
"ali_aes_process: invalid hash type(%d)\n",
aes_ctx->type);
}
if (ret != ALI_CRYPTO_SUCCESS) {
if (aes_ctx->is_enc) {
MBED_DBG_E("ali_aes_process: encrypt(%d) fail!\n", aes_ctx->type);
} else {
MBED_DBG_E("ali_aes_process: decrypt(%d) fail!\n", aes_ctx->type);
}
return ALI_CRYPTO_ERROR;
}
aes_ctx->status = CRYPTO_STATUS_PROCESSING;
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_aes_finish(const uint8_t *src, size_t src_size,
uint8_t *dst, size_t *dst_size,
sym_padding_t padding, void *context)
{
ali_crypto_result ret = ALI_CRYPTO_ERROR;
aes_ctx_t * aes_ctx;
(void)padding;
if ((src == NULL && src_size != 0) ||
((dst_size != NULL) && (dst == NULL && *dst_size != 0)) ||
context == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG, "ali_aes_finish: bad input args!\n");
}
aes_ctx = (aes_ctx_t *)context;
if (!IS_VALID_CTX_MAGIC(aes_ctx->magic)) {
PRINT_RET(ALI_CRYPTO_INVALID_CONTEXT, "ali_aes_finish: bad magic!\n");
}
if ((aes_ctx->status != CRYPTO_STATUS_INITIALIZED) &&
(aes_ctx->status != CRYPTO_STATUS_PROCESSING)) {
PRINT_RET(ALI_CRYPTO_ERR_STATE, "ali_aes_finish: bad status(%d)\n",
(int)aes_ctx->status);
}
switch (aes_ctx->type) {
case AES_ECB: {
if (aes_ctx->is_enc) {
ret = csi_tee_aes_encrypt_ecb(src, src_size, key_copy,
keylen_copy, dst);
} else {
ret = csi_tee_aes_decrypt_ecb(src, src_size, key_copy,
keylen_copy, dst);
}
break;
}
case AES_CBC: {
if (aes_ctx->is_enc) {
ret = csi_tee_aes_encrypt_cbc(src, src_size, key_copy,
keylen_copy, aes_ctx->iv, dst);
} else {
ret = csi_tee_aes_decrypt_cbc(src, src_size, key_copy,
keylen_copy, aes_ctx->iv, dst);
}
break;
}
case AES_CTR: {
break;
}
#if defined(MBEDTLS_CIPHER_MODE_CFB)
case AES_CFB8:
case AES_CFB128: {
break;
}
#endif
case AES_CTS:
case AES_XTS:
default:
PRINT_RET(ALI_CRYPTO_NOSUPPORT,
"ali_aes_finish: invalid aes type(%d)\n", aes_ctx->type);
}
if (ret != ALI_CRYPTO_SUCCESS) {
mbedtls_aes_free(&(aes_ctx->ctx));
PRINT_RET(ret, "ali_aes_process: aes type(%d) final fail(%08x)\n",
aes_ctx->type, ret);
}
CLEAN_CTX_MAGIC(aes_ctx->magic);
aes_ctx->status = CRYPTO_STATUS_FINISHED;
aes_ctx->offset = 0;
mbedtls_aes_free(&(aes_ctx->ctx));
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_aes_reset(void *context)
{
aes_ctx_t *aes_ctx;
if (context == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG, "ali_aes_reset: bad input args!\n");
}
aes_ctx = (aes_ctx_t *)context;
#if 0
if (!IS_VALID_CTX_MAGIC(aes_ctx->magic)) {
PRINT_RET(ALI_CRYPTO_INVALID_CONTEXT, "ali_aes_reset: bad magic!\n");
}
#endif
OSA_memset(aes_ctx, 0, sizeof(aes_ctx_t));
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_aes_copy_context(void *dst_ctx, void *src_ctx)
{
aes_ctx_t *aes_ctx_src, *aes_ctx_dst;
if ((dst_ctx == NULL) || (src_ctx == NULL)) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG,
"ali_aes_copy_context: bad input args!\n");
}
aes_ctx_src = (aes_ctx_t *)src_ctx;
if (!IS_VALID_CTX_MAGIC(aes_ctx_src->magic)) {
PRINT_RET(ALI_CRYPTO_INVALID_CONTEXT,
"ali_aes_copy_context: bad magic!\n");
}
/* only can copy to one un-initialized context */
aes_ctx_dst = (aes_ctx_t *)dst_ctx;
if ((IS_VALID_CTX_MAGIC(aes_ctx_dst->magic)) &&
((aes_ctx_dst->status == CRYPTO_STATUS_INITIALIZED) ||
(aes_ctx_dst->status == CRYPTO_STATUS_PROCESSING) ||
(aes_ctx_dst->status == CRYPTO_STATUS_FINISHED))) {
PRINT_RET(ALI_CRYPTO_ERR_STATE, "ali_aes_init: bad dst status(%d)\n",
(int)aes_ctx_dst->status);
}
OSA_memcpy(aes_ctx_dst, aes_ctx_src, sizeof(aes_ctx_t));
return ALI_CRYPTO_SUCCESS;
}

View file

@ -0,0 +1,455 @@
/**
* Copyright (C) 2017 The YunOS Project. All rights reserved.
*/
#include "mbed_crypto.h"
#include "ali_crypto.h"
#include "drv_tee.h"
ali_crypto_result ali_hash_get_ctx_size(hash_type_t type, size_t *size)
{
if (NULL == size) {
MBED_DBG_E("get_ctx_size: bad input!\n");
return ALI_CRYPTO_INVALID_ARG;
}
switch (type) {
case SHA1:
case SHA224:
case SHA256:
case SHA384:
case SHA512:
case MD5:
break;
default:
MBED_DBG_E("get_ctx_size: invalid hash type(%d)\n", type);
return ALI_CRYPTO_INVALID_TYPE;
}
*size = sizeof(hash_ctx_t);
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_hash_init(hash_type_t type, void *context)
{
hash_ctx_t *hash_ctx;
if (NULL == context) {
MBED_DBG_E("ali_hash_init: bad ctx!\n");
return ALI_CRYPTO_INVALID_CONTEXT;
}
hash_ctx = (hash_ctx_t *)context;
if ((IS_VALID_CTX_MAGIC(hash_ctx->magic) &&
hash_ctx->status != CRYPTO_STATUS_FINISHED) &&
hash_ctx->status != CRYPTO_STATUS_CLEAN) {
MBED_DBG_E("ali_hash_init: bad status(%d)\n", (int)hash_ctx->status);
return ALI_CRYPTO_ERR_STATE;
}
switch (type) {
#ifdef MBEDTLS_SHA1_C
case SHA1: {
#if 0
mbedtls_sha1_init(&hash_ctx->sha1_ctx);
mbedtls_sha1_starts(&hash_ctx->sha1_ctx);
#else
csi_tee_sha_start(TEE_SHA1, &hash_ctx->sha1_ctx);
#endif
break;
}
#endif
#ifdef MBEDTLS_SHA256_C
case SHA224: {
#if 0
mbedtls_sha256_init(&hash_ctx->sha256_ctx);
mbedtls_sha256_starts(&hash_ctx->sha256_ctx, 1);
#else
csi_tee_sha_start(TEE_SHA224, &hash_ctx->sha256_ctx);
#endif
break;
}
case SHA256: {
#if 0
mbedtls_sha256_init(&hash_ctx->sha256_ctx);
mbedtls_sha256_starts(&hash_ctx->sha256_ctx, 0);
#else
csi_tee_sha_start(TEE_SHA256, &hash_ctx->sha256_ctx);
#endif
break;
}
#endif
#ifdef MBEDTLS_SHA512_C
case SHA384: {
mbedtls_sha512_init(&hash_ctx->sha512_ctx);
mbedtls_sha512_starts(&hash_ctx->sha512_ctx, 1);
break;
}
case SHA512: {
mbedtls_sha512_init(&hash_ctx->sha512_ctx);
mbedtls_sha512_starts(&hash_ctx->sha512_ctx, 0);
break;
}
#endif
#ifdef MBEDTLS_MD5_C
case MD5: {
mbedtls_md5_init(&hash_ctx->md5_ctx);
mbedtls_md5_starts(&hash_ctx->md5_ctx);
break;
}
#endif
default:
MBED_DBG_E("ali_hash_init: invalid hash type(%d)\n", type);
return ALI_CRYPTO_INVALID_TYPE;
}
hash_ctx->type = type;
hash_ctx->status = CRYPTO_STATUS_INITIALIZED;
INIT_CTX_MAGIC(hash_ctx->magic);
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_hash_update(const uint8_t *src, size_t size,
void *context)
{
hash_ctx_t *hash_ctx;
if (context == NULL) {
MBED_DBG_E("ali_hash_update: bad ctx!\n");
return ALI_CRYPTO_INVALID_CONTEXT;
}
if (src == NULL && size != 0) {
MBED_DBG_E("ali_hash_update: bad args!\n");
return ALI_CRYPTO_INVALID_ARG;
}
hash_ctx = (hash_ctx_t *)context;
if (!IS_VALID_CTX_MAGIC(hash_ctx->magic)) {
MBED_DBG_E("ali_hash_update: bad magic!\n");
return ALI_CRYPTO_INVALID_CONTEXT;
}
if ((hash_ctx->status != CRYPTO_STATUS_INITIALIZED) &&
(hash_ctx->status != CRYPTO_STATUS_PROCESSING)) {
MBED_DBG_E("ali_hash_update: bad status(%d)\n", (int)hash_ctx->status);
return ALI_CRYPTO_ERR_STATE;
}
switch (hash_ctx->type) {
#ifdef MBEDTLS_SHA1_C
case SHA1: {
#if 0
mbedtls_sha1_update(&hash_ctx->sha1_ctx,
(const unsigned char *)src, size);
#else
csi_tee_sha_update(src, size, &hash_ctx->sha1_ctx);
#endif
break;
}
#endif
#ifdef MBEDTLS_SHA256_C
case SHA224: {
#if 0
mbedtls_sha256_update(&hash_ctx->sha256_ctx,
(const unsigned char *)src, size);
#else
csi_tee_sha_update(src, size, &hash_ctx->sha256_ctx);
#endif
break;
}
case SHA256: {
#if 0
mbedtls_sha256_update(&hash_ctx->sha256_ctx,
(const unsigned char *)src, size);
#else
csi_tee_sha_update(src, size, &hash_ctx->sha256_ctx);
#endif
break;
}
#endif
#ifdef MBEDTLS_SHA512_C
case SHA384: {
mbedtls_sha512_update(&hash_ctx->sha512_ctx,
(const unsigned char *)src, size);
break;
}
case SHA512: {
mbedtls_sha512_update(&hash_ctx->sha512_ctx,
(const unsigned char *)src, size);
break;
}
#endif
#ifdef MBEDTLS_MD5_C
case MD5: {
mbedtls_md5_update(&hash_ctx->md5_ctx, (const unsigned char *)src,
size);
break;
}
#endif
default:
MBED_DBG_E("ali_hash_update: invalid hash type(%d)\n",
hash_ctx->type);
return ALI_CRYPTO_INVALID_TYPE;
}
hash_ctx->status = CRYPTO_STATUS_PROCESSING;
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_hash_final(uint8_t *dgst, void *context)
{
hash_ctx_t *hash_ctx;
if (context == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_CONTEXT,
"ali_hash_final: invalid context!\n");
}
if (dgst == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG, "ali_hash_final: bad input args!\n");
}
hash_ctx = (hash_ctx_t *)context;
if (!IS_VALID_CTX_MAGIC(hash_ctx->magic)) {
MBED_DBG_E("ali_hash_final: bad magic!\n");
return ALI_CRYPTO_INVALID_CONTEXT;
}
if ((hash_ctx->status != CRYPTO_STATUS_INITIALIZED) &&
(hash_ctx->status != CRYPTO_STATUS_PROCESSING)) {
MBED_DBG_E("ali_hash_final: bad status(%d)\n", (int)hash_ctx->status);
return ALI_CRYPTO_ERR_STATE;
}
switch (hash_ctx->type) {
#ifdef MBEDTLS_SHA1_C
case SHA1: {
#if 0
mbedtls_sha1_finish(&hash_ctx->sha1_ctx, (unsigned char *)dgst);
mbedtls_sha1_free(&hash_ctx->sha1_ctx);
#else
csi_tee_sha_finish(dgst, &hash_ctx->sha1_ctx);
#endif
break;
}
#endif
#ifdef MBEDTLS_SHA256_C
case SHA224: {
#if 0
mbedtls_sha256_finish(&hash_ctx->sha256_ctx, (unsigned char *)dgst);
mbedtls_sha256_free(&hash_ctx->sha256_ctx);
#else
csi_tee_sha_finish(dgst, &hash_ctx->sha256_ctx);
#endif
break;
}
case SHA256: {
#if 0
mbedtls_sha256_finish(&hash_ctx->sha256_ctx, (unsigned char *)dgst);
mbedtls_sha256_free(&hash_ctx->sha256_ctx);
#else
csi_tee_sha_finish(dgst, &hash_ctx->sha256_ctx);
#endif
break;
}
#endif
#ifdef MBEDTLS_SHA512_C
case SHA384: {
mbedtls_sha512_finish(&hash_ctx->sha512_ctx, (unsigned char *)dgst);
mbedtls_sha512_free(&hash_ctx->sha512_ctx);
break;
}
case SHA512: {
mbedtls_sha512_finish(&hash_ctx->sha512_ctx, (unsigned char *)dgst);
mbedtls_sha512_free(&hash_ctx->sha512_ctx);
break;
}
#endif
#ifdef MBEDTLS_MD5_C
case MD5: {
mbedtls_md5_finish(&hash_ctx->md5_ctx, (unsigned char *)dgst);
mbedtls_md5_free(&hash_ctx->md5_ctx);
break;
}
#endif
default:
MBED_DBG_E("ali_hash_final: invalid hash type(%d)\n",
hash_ctx->type);
return ALI_CRYPTO_INVALID_TYPE;
}
CLEAN_CTX_MAGIC(hash_ctx->magic);
hash_ctx->status = CRYPTO_STATUS_FINISHED;
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_hash_digest(hash_type_t type, const uint8_t *src,
size_t size, uint8_t *dgst)
{
hash_ctx_t hash_ctx;
if ((src == NULL && size != 0) || dgst == NULL) {
MBED_DBG_E("ali_hash_digest: bad input args!\n");
return ALI_CRYPTO_INVALID_ARG;
}
switch (type) {
#ifdef MBEDTLS_SHA1_C
case SHA1: {
#if 0
mbedtls_sha1_init(&hash_ctx.sha1_ctx);
mbedtls_sha1_starts(&hash_ctx.sha1_ctx);
mbedtls_sha1_update(&hash_ctx.sha1_ctx,
(const unsigned char *)src, size);
mbedtls_sha1_finish(&hash_ctx.sha1_ctx, (unsigned char *)dgst);
mbedtls_sha1_free(&hash_ctx.sha1_ctx);
#else
csi_tee_sha_digest(src, size, dgst, TEE_SHA1);
#endif
break;
}
#endif
#ifdef MBEDTLS_SHA256_C
case SHA224: {
#if 0
mbedtls_sha256_init(&hash_ctx.sha256_ctx);
mbedtls_sha256_starts(&hash_ctx.sha256_ctx, 1);
mbedtls_sha256_update(&hash_ctx.sha256_ctx,
(const unsigned char *)src, size);
mbedtls_sha256_finish(&hash_ctx.sha256_ctx, (unsigned char *)dgst);
mbedtls_sha256_free(&hash_ctx.sha256_ctx);
#else
csi_tee_sha_digest(src, size, dgst, TEE_SHA224);
#endif
break;
}
case SHA256: {
#if 0
mbedtls_sha256_init(&hash_ctx.sha256_ctx);
mbedtls_sha256_starts(&hash_ctx.sha256_ctx, 0);
mbedtls_sha256_update(&hash_ctx.sha256_ctx,
(const unsigned char *)src, size);
mbedtls_sha256_finish(&hash_ctx.sha256_ctx, (unsigned char *)dgst);
mbedtls_sha256_free(&hash_ctx.sha256_ctx);
#else
csi_tee_sha_digest(src, size, dgst, TEE_SHA256);
#endif
break;
}
#endif
#ifdef MBEDTLS_SHA512_C
case SHA384: {
mbedtls_sha512_init(&hash_ctx.sha512_ctx);
mbedtls_sha512_starts(&hash_ctx.sha512_ctx, 1);
mbedtls_sha512_update(&hash_ctx.sha512_ctx,
(const unsigned char *)src, size);
mbedtls_sha512_finish(&hash_ctx.sha512_ctx, (unsigned char *)dgst);
mbedtls_sha512_free(&hash_ctx.sha512_ctx);
break;
}
case SHA512: {
mbedtls_sha512_init(&hash_ctx.sha512_ctx);
mbedtls_sha512_starts(&hash_ctx.sha512_ctx, 0);
mbedtls_sha512_update(&hash_ctx.sha512_ctx,
(const unsigned char *)src, size);
mbedtls_sha512_finish(&hash_ctx.sha512_ctx, (unsigned char *)dgst);
mbedtls_sha512_free(&hash_ctx.sha512_ctx);
break;
}
#endif
#ifdef MBEDTLS_MD5_C
case MD5: {
mbedtls_md5_init(&hash_ctx.md5_ctx);
mbedtls_md5_starts(&hash_ctx.md5_ctx);
mbedtls_md5_update(&hash_ctx.md5_ctx, (const unsigned char *)src,
size);
mbedtls_md5_finish(&hash_ctx.md5_ctx, (unsigned char *)dgst);
mbedtls_md5_free(&hash_ctx.md5_ctx);
break;
}
#endif
default:
MBED_DBG_E("ali_hash_digest: invalid hash type(%d)\n", type);
return ALI_CRYPTO_INVALID_TYPE;
}
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_hash_reset(void *context)
{
hash_ctx_t *hash_ctx;
if (context == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_CONTEXT,
"ali_hash_reset: invalid context!\n");
}
hash_ctx = (hash_ctx_t *)context;
#if 0
if (!IS_VALID_CTX_MAGIC(hash_ctx->magic)) {
PRINT_RET(ALI_CRYPTO_INVALID_CONTEXT, "ali_hash_reset: bad magic!");
}
#endif
OSA_memset(hash_ctx, 0, sizeof(hash_ctx_t));
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_hash_copy_context(void *dst_ctx, void *src_ctx)
{
hash_ctx_t *hash_ctx_src, *hash_ctx_dst;
if ((src_ctx == NULL) || (dst_ctx == NULL)) {
MBED_DBG_E("ali_hash_copy_context: bad input args!\n");
return ALI_CRYPTO_INVALID_ARG;
}
hash_ctx_src = (hash_ctx_t *)src_ctx;
if (!IS_VALID_CTX_MAGIC(hash_ctx_src->magic)) {
MBED_DBG_E("ali_hash_copy_context: bad magic!\n");
return ALI_CRYPTO_INVALID_CONTEXT;
}
/* only can copy to one un-initialized context */
hash_ctx_dst = (hash_ctx_t *)dst_ctx;
if ((IS_VALID_CTX_MAGIC(hash_ctx_dst->magic)) &&
((hash_ctx_dst->status == CRYPTO_STATUS_INITIALIZED) ||
(hash_ctx_dst->status == CRYPTO_STATUS_PROCESSING) ||
(hash_ctx_dst->status == CRYPTO_STATUS_FINISHED))) {
MBED_DBG_E("ali_hash_copy_context: bad status(%d)\n",
(int)hash_ctx_dst->status);
return ALI_CRYPTO_ERR_STATE;
}
OSA_memcpy(hash_ctx_dst, hash_ctx_src, sizeof(hash_ctx_t));
return ALI_CRYPTO_SUCCESS;
}

View file

@ -0,0 +1,30 @@
/**
* Copyright (C) 2017 The YunOS Project. All rights reserved.
**/
#include "ali_crypto.h"
#include "mbed_crypto.h"
#include "drv_tee.h"
ali_crypto_result ali_rand_gen(uint8_t *buf, size_t len)
{
if (buf == NULL || len == 0) {
MBED_DBG_E("ali_rand_gen: invalid input args!\n");
return ALI_CRYPTO_INVALID_ARG;
}
if (csi_tee_rand_generate(buf, len)) {
MBED_DBG_E("ali_rand_gen: fail!\n");
return ALI_CRYPTO_ERR_STATE;
}
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_seed(uint8_t *seed, size_t seed_len)
{
(void)seed_len;
csi_tee_rand_seed(*(uint32_t *)seed);
return ALI_CRYPTO_SUCCESS;
}

File diff suppressed because it is too large Load diff

Binary file not shown.

View file

@ -0,0 +1,83 @@
#
# Copyright (C) 2017 The YunOS Project. All rights reserved.
#
TOP := ../
#TOOLCHAIN_PRE := arm-none-eabi-
#TOOLCHAIN_PRE := arm-linux-gnueabihf-
TOOLCHAIN_PRE :=
CC = $(TOOLCHAIN_PRE)gcc
LD = $(TOOLCHAIN_PRE)ld
AR = $(TOOLCHAIN_PRE)ar
RANLIB = $(TOOLCHAIN_PRE)ranlib
LOCAL_DIR := .
CRYPT_TEST := N
CRYPT_TYPE := MBED
LIB := $(TOP)/mbedtls/library/libmbedcrypto.a
CFLAGS = -Wall -g -O2 -I$(LOCAL_DIR)/mbed/inc -I$(LOCAL_DIR)/sw \
-I$(LOCAL_DIR)/inc -I$(TOP)/mbedtls/include/mbedtls/ \
-I$(TOP)/../yunos_iot/aos/include
ifeq ($(m32),1)
CFLAGS += -m32
endif
CFLAGS += -Wformat
CFLAGS += -DCONFIG_CRYPT_MBED=1 -DCONFIG_DBG_CRYPT=1
#-DCONFIG_NO_ALIOS=1
ifeq ($(gcov),1)
CFLAGS += -fprofile-arcs -ftest-coverage
LDFLAGS += --coverage
endif
ifeq ($(CRYPT_TYPE), MBED)
SRCS += \
$(LOCAL_DIR)/mbed/cipher/aes.c \
$(LOCAL_DIR)/mbed/hash/hash.c \
$(LOCAL_DIR)/mbed/asym/rsa.c \
$(LOCAL_DIR)/mbed/mac/hmac.c \
endif
ifeq ($(CRYPT_TEST), Y)
#TEST_SRCS += $(LOCAL_DIR)/mbed/test/mbed_rsa_test.c
TEST_SRCS += \
$(LOCAL_DIR)/test/ali_crypto_test.c \
$(LOCAL_DIR)/test/ali_crypto_test_comm.c \
$(LOCAL_DIR)/test/ali_crypto_test_hash.c \
$(LOCAL_DIR)/test/ali_crypto_test_rand.c \
$(LOCAL_DIR)/test/ali_crypto_test_aes.c \
$(LOCAL_DIR)/test/ali_crypto_test_rsa.c \
$(LOCAL_DIR)/test/ali_crypto_test_hmac.c \
CFLAGS += -I$(LOCAL_DIR)/test/inc
OUT_E := ali_crypto_test
endif
SRCS += $(LOCAL_DIR)/sw/ali_crypto_rand.c
CFLAGS += -I$(LOCAL_DIR)/sw/inc
SRCS += $(LOCAL_DIR)/ali_crypto.c
OBJS := $(patsubst %.cxx,%.o,$(patsubst %.c,%.o,$(SRCS)))
TEST_OBJS := $(patsubst %.cxx,%.o,$(patsubst %.c,%.o,$(TEST_SRCS)))
OUT := libalicrypto.a
all: $(OUT_E) $(OUT) $(OBJS) $(TEST_OBJS)
$(OUT): $(OBJS) $(LIB)
$(AR) rc $(OUT) $(OBJS)
$(RANLIB) $(OUT)
$(OUT_E): $(OBJS) $(TEST_OBJS) $(LIB)
$(CC) $(LDFLAGS) $(CFLAGS) $(LIB) $^ -o $@.elf
$(CC) $(LDFLAGS) $(CFLAGS) $(LIB) $^ -o $@
%.o: %.c
echo $(CC) $(CFLAGS) $<
$(CC) -c $(CFLAGS) $< -o $*.o
clean:
rm -f $(OBJS) $(OUT_E) $(OUT_E).elf $(OUT) $(TEST_OBJS)

View file

@ -0,0 +1,51 @@
/**
* Copyright (C) 2016 The YunOS Project. All rights reserved.
**/
#include "ali_crypto.h"
#if CONFIG_CRYPT_MBED
#include "mbed_crypto.h"
#endif
#if CONFIG_CRYPT_MBED
ali_crypto_result mbed_crypto_init(void)
{
ali_crypto_result ret = ALI_CRYPTO_SUCCESS;
#if defined(MBEDTLS_THREADING_ALT)
//mbedtls_threading_set_alt(OSA_mutex_init, OSA_mutex_free, OSA_mutex_lock,
// OSA_mutex_unlock);
#endif
/* TODO */
return ret;
}
void mbed_crypto_cleanup(void)
{
/* TODO */
#if defined(MBEDTLS_THREADING_ALT)
//mbedtls_threading_free_alt();
#endif
return;
}
#endif
ali_crypto_result ali_crypto_init(void)
{
ali_crypto_result ret = ALI_CRYPTO_SUCCESS;
#if CONFIG_CRYPT_MBED
ret = mbed_crypto_init();
#endif
return ret;
}
void ali_crypto_cleanup(void)
{
#if CONFIG_CRYPT_MBED
mbed_crypto_cleanup();
#endif
return;
}

View file

@ -0,0 +1,7 @@
#!/bin/bash
make gcov=1
./ali_crypto_test
sudo lcov -c -b . -d ./mbed -d ./sw -o test.info
genhtml test.info -o yos_test_report

View file

@ -0,0 +1,762 @@
/**
* Copyright (C) 2016 The YunOS Project. All rights reserved.
**/
/* Alibaba TEE Crypto API: version 1.1 */
#ifndef _ALI_CRYPTO_H_
#define _ALI_CRYPTO_H_
#include "ali_crypto_types.h"
typedef enum _ali_crypto_result
{
ALI_CRYPTO_ERROR = (int)0xffff0000, /* Generic Error */
ALI_CRYPTO_NOSUPPORT, /* Scheme not support */
ALI_CRYPTO_INVALID_KEY, /* Invalid Key in asymmetric scheme: RSA/DSA/ECCP/DH
etc */
ALI_CRYPTO_INVALID_TYPE, /* Invalid
aes_type/des_type/authenc_type/hash_type/cbcmac_type/cmac_type
*/
ALI_CRYPTO_INVALID_CONTEXT, /* Invalid context in multi-thread
cipher/authenc/mac/hash etc */
ALI_CRYPTO_INVALID_PADDING, /* Invalid
sym_padding/rsassa_padding/rsaes_padding */
ALI_CRYPTO_INVALID_AUTHENTICATION, /* Invalid authentication in
AuthEnc(AES-CCM/AES-GCM)/asymmetric
verify(RSA/DSA/ECCP DSA) */
ALI_CRYPTO_INVALID_ARG, /* Invalid arguments */
ALI_CRYPTO_INVALID_PACKET, /* Invalid packet in asymmetric enc/dec(RSA) */
ALI_CRYPTO_LENGTH_ERR, /* Invalid Length in arguments */
ALI_CRYPTO_OUTOFMEM, /* Memory alloc NULL */
ALI_CRYPTO_SHORT_BUFFER, /* Output buffer is too short to store result */
ALI_CRYPTO_NULL, /* NULL pointer in arguments */
ALI_CRYPTO_ERR_STATE, /* Bad state in mulit-thread cipher/authenc/mac/hash
etc */
ALI_CRYPTO_SUCCESS = 0, /* Success */
} ali_crypto_result;
#define AES_BLOCK_SIZE \
16 /* don't change this value,since AES only support 16 byte block size */
#define AES_IV_SIZE 16
#define DES_BLOCK_SIZE 8
#define DES_IV_SIZE 8
typedef enum _sym_padding_t
{
SYM_NOPAD = 0,
SYM_PKCS5_PAD = 1,
SYM_ZERO_PAD = 2,
} sym_padding_t;
typedef enum _aes_type_t
{
AES_ECB = 0,
AES_CBC = 1,
AES_CTR = 2,
AES_CTS = 3,
AES_XTS = 4,
AES_CFB8 = 6,
AES_CFB128 = 7,
} aes_type_t;
typedef enum _des_type_t
{
DES_ECB = 0,
DES_CBC = 1,
DES3_ECB = 2,
DES3_CBC = 3,
} des_type_t;
typedef enum _authenc_type_t
{
AES_CCM = 0,
AES_GCM = 1,
} authenc_type_t;
typedef enum _hash_type_t
{
HASH_NONE = 0,
SHA1 = 1,
SHA224 = 2,
SHA256 = 3,
SHA384 = 4,
SHA512 = 5,
MD5 = 6,
} hash_type_t;
enum
{
MD5_HASH_SIZE = 16,
SHA1_HASH_SIZE = 20,
SHA224_HASH_SIZE = 28,
SHA256_HASH_SIZE = 32,
SHA384_HASH_SIZE = 48,
SHA512_HASH_SIZE = 64,
MAX_HASH_SIZE = 64,
};
#define HASH_SIZE(type) \
(((type) == SHA1) \
? (SHA1_HASH_SIZE) \
: (((type) == SHA224) \
? (SHA224_HASH_SIZE) \
: (((type) == SHA256) \
? (SHA256_HASH_SIZE) \
: (((type) == SHA384) \
? (SHA384_HASH_SIZE) \
: (((type) == SHA512) \
? (SHA512_HASH_SIZE) \
: (((type) == MD5) ? (MD5_HASH_SIZE) : (0)))))))
typedef enum _cbcmac_type_t
{
AESCBCMAC = 0,
DESCBCMAC = 1,
DES3CBCMAC = 2,
} cbcmac_type_t;
typedef enum _cmac_type_t
{
AESCMAC = 0,
} cmac_type_t;
typedef enum _rsa_key_attr_t
{
RSA_MODULUS = 0x130,
RSA_PUBLIC_EXPONENT = 0x230,
RSA_PRIVATE_EXPONENT = 0x330,
RSA_PRIME1 = 0x430,
RSA_PRIME2 = 0x530,
RSA_EXPONENT1 = 0x630,
RSA_EXPONENT2 = 0x730,
RSA_COEFFICIENT = 0x830,
} rsa_key_attr_t;
typedef enum _dh_key_attr_t
{
DH_PRIME = 0x140,
DH_BASE = 0x240,
DH_PRIVATE = 0x340,
DH_PUBLIC = 0x440,
DH_SUBPRIME = 0x540,
DH_X_BITS = 0x640,
} dh_key_attr_t;
typedef enum _dsa_key_attr_t
{
DSA_PRIME = 0x150,
DSA_SUBPRIME = 0x250,
DSA_BASE = 0x350,
DSA_PRIVATE = 0x450,
DSA_PUBLIC = 0x550,
} dsa_key_attr_t;
typedef enum _rsa_pad_type_t
{
RSA_NOPAD = 0,
/* encrypt */
RSAES_PKCS1_V1_5 = 10,
RSAES_PKCS1_OAEP_MGF1 = 11,
/* sign */
RSASSA_PKCS1_V1_5 = 20,
RSASSA_PKCS1_PSS_MGF1 = 21,
} rsa_pad_type_t;
typedef struct _rsa_padding_t
{
rsa_pad_type_t type;
union
{
struct
{
hash_type_t type;
} rsaes_oaep;
struct
{
hash_type_t type; /* md5/sha1/sha224/sha256/sha384/sha512 */
} rsassa_v1_5;
struct
{
hash_type_t type; /* sha1/sha224/sha256/sha384/sha512 */
size_t salt_len;
} rsassa_pss;
} pad;
} rsa_padding_t;
typedef enum _dsa_padding_t
{
DSA_SHA1 = 0,
DSA_SHA224 = 1,
DSA_SHA256 = 2,
} dsa_padding_t;
enum
{
CRYPTO_STATUS_CLEAN = 0,
CRYPTO_STATUS_INITIALIZED = 1,
CRYPTO_STATUS_PROCESSING = 2,
CRYPTO_STATUS_FINISHED = 3,
};
/* internal data types */
typedef struct __rsa_keypair rsa_keypair_t;
typedef struct __rsa_pubkey rsa_pubkey_t;
typedef struct __dsa_keypair dsa_keypair_t;
typedef struct __dsa_pubkey dsa_pubkey_t;
typedef struct __dh_keypair dh_keypair_t;
typedef struct __dh_pubkey dh_pubkey_t;
typedef struct __ecc_keypair ecc_keypair_t;
typedef struct __ecc_pubkey ecc_pubkey_t;
/********************************************************************/
/* SYM */
/********************************************************************/
/*
* type[in]: must be AES_ECB/AES_CBC/AES_CTR/AES_CTS/AES_XTS
* size[out]: check size != NULL
* -- caller will alloc "size" memory as context buffer later
*/
ali_crypto_result ali_aes_get_ctx_size(aes_type_t type, size_t *size);
/*
* type[in]: must be AES_ECB/AES_CBC/AES_CTR/AES_CTS/AES_XTS
* is_enc[in]: [true] for encrypt, [false] for decrypt
* key1[in]: the encrypt key
* key2[in]: the tweak encrypt key for XTS mode
* keybytes[in]: the key length of the keys(each) in bytes, should be
* 16/24/32 bytes iv[in]: only valid for
* AES_CBC/AES_CTR/AES_CTS/AES_XTS
* -- function can read 16 bytes from this address as the
* internal iv context[in/out]: caller allocated memory used as internal
* context, which size is got through ali_aes_get_ctx_size
* -- [in]: status of context should be CLEAN or FINISHED
* -- [out]: status of context is changed to INITIALIZED
*/
ali_crypto_result ali_aes_init(aes_type_t type, bool is_enc,
const uint8_t *key1, const uint8_t *key2,
size_t keybytes, const uint8_t *iv,
void *context);
/*
* src[in]: plaintext for encrypt, ciphertext for decrypt
* dst[out]: ciphertext for encrypt, plaintext for decrypt
* size[in]: the number of bytes to process
* -- ECB/CBC/CTS/XTS, must be multiple of the cipher block
* size
* -- CTR, any positive integer
* context[in/out]: internal context
* -- [in]: status of context should be INITED or PROCESSING
* -- [out]: status of context is changed to PROCESSING
*/
ali_crypto_result ali_aes_process(const uint8_t *src, uint8_t *dst, size_t size,
void *context);
/*
* src[in]: source data, plaintext for encrypt/ciphertext for decrypt
* -- may be NULL, which identify that no input data, only
* terminate crypto src_size[in]: the number of bytes to process, src_size
* == 0 if src == NULL
* -- encrypt: SYM_NOPAD - must be multiple of the cipher
* block size
* -- decrypt: ECB/CBC - must be multiple of the cipher
* block size dst[out]: destination data, which is used to save
* processed data
* -- may be NULL if no input src data(src == NULL &&
* src_size == 0)
* -- ciphertext for encrypt, plaintext for decrypt
* -- if no SYM_NOPAD, should remove padding data
* accordingly dst_size[in/out]: the length of processed data, may be NULL if
* dst == NULL
* -- [in]: buffer size
* -- [out]: the actual encrypted/decrypted data size
* padding[in]: padding type for aes mode
* -- ECB/CBC: only support SYM_NOPAD
* -- CTR/CTS/XTS: padding is ignored
* context[in/out]: internal context
* -- [in]: status of context should be INITED or
* PROCESSING
* -- [out]: status of context is changed to FINISHED
*/
ali_crypto_result ali_aes_finish(const uint8_t *src, size_t src_size,
uint8_t *dst, size_t *dst_size,
sym_padding_t padding, void *context);
ali_crypto_result ali_aes_reset(void *context);
ali_crypto_result ali_aes_copy_context(void *dst_ctx, void *src_ctx);
/* des include des3 */
/*
type: must be DES_ECB/DES_CBC/DES3_ECB/DES3_CBC
size: check size != NULL
*/
ali_crypto_result ali_des_get_ctx_size(des_type_t type, size_t *size);
/*
type: must be DES_ECB/DES_CBC/DES3_ECB/DES3_CBC
is_enc: [true] for encrypt, [false] for decrypt.
key: function will read 'keybytes' of data as key.
keybytes: for DES_ECB/DES_CBC, must be 64.
for DES3_ECB/DES3_CBC, must be 128 or 192.
iv: for DES_ECB/DES3_ECB: must be NULL.
for DES_CBC/DES3_CBC: function will read 8 bytes as algo iv.
context: function will use size which return from function
'ali_des_get_ctx_size' as internal context. function will check the [status[ of
'context', must be CLEAN or FINISH. function will initialize the [status] of
'context' to INIT. function will save the 'type', 'is_enc', or maybe 'iv',
'key', 'keybytes' in 'context'. function will initialize the 'context' to a
valid context.
*/
ali_crypto_result ali_des_init(des_type_t type, bool is_enc, const uint8_t *key,
size_t keybytes, const uint8_t *iv,
void *context);
/*
src: function will read 'size' of data from this area as source data.
MUST be NULL if 'size' is 0
dst: function will write 'size' of data to this area as destination data.
MUST be NULL if 'size' is 0
size: the length of source data.
must be multiple of 8 bytes. or 0.
if size == 0, src MUST be NULL, dst MUST be NULL, return
TEE_SUCCESS. context: function will use size which return from function
'ali_des_get_ctx_size' as internal context. function will check it is a valid
context. function will check the [status] of 'context', must be INIT or PROCESS.
function will change the [status] of 'context' to PROCESS.
function will do encrypt or decrypt indicated by the content in
'context'.
*/
ali_crypto_result ali_des_process(const uint8_t *src, uint8_t *dst, size_t size,
void *context);
/*
src: function will read 'src_size' of data from this area as source data.
MUST be NULL if 'src_size' is 0.
src_size: the length of source data. this have different rules for differnt
'type' and 'padding'. a. for 'padding' is SYM_NOPAD: a.1 MUST be multiple of 16
bytes. or 0. b. for other 'padding': b.1 can be any integer or 0. if 'src_size'
== 0, 'src' MUST be NULL, 'dst' MUST be NULL, and this function will reaturn
SUCCESS. dst: function will write certain length which is retuned by
'dst_size' of data to this area as destination data. MUST be NULL if 'size' is 0
dst_size: function will wirte some integer to this area to indicate the length
of destination data. the return value depends on 'src_size' and 'padding' a.1
for 'padding' is SYM_NOPAD, dst_size is equal to src_size. a.2 for other
'padding', 'dst_size' is 16 bytes align up of 'src_size'. padding: the
padding type of finish. can be anyone of SYM_NOPAD/SYM_PKCS5_PAD/SYM_ZERO_PAD.
context: function will use size which return from function
'ali_des_get_ctx_size' as internal context. function will check it is a valid
context. function will check the [status] of 'context', must be INIT or PROCESS.
function will change the [status] of 'context' to FINISH.
function will do encrypt or decrypt indicated by the content in
'context'. function MUST clean the content of context before this fucntion
return.
*/
ali_crypto_result ali_des_finish(const uint8_t *src, size_t src_size,
uint8_t *dst, size_t *dst_size,
sym_padding_t padding, void *context);
ali_crypto_result ali_des_reset(void *context);
ali_crypto_result ali_des_copy_context(void *dst_ctx, void *src_ctx);
/********************************************************************/
/* Authenticated Encryption */
/********************************************************************/
/*
type: MUST be AES_CCM/AES_GCM
size: check size != NULL
*/
ali_crypto_result ali_authenc_get_ctx_size(authenc_type_t type, size_t *size);
/*
type: MUST be AES_CCM/AES_GCM
is_enc: [true] for encrypt, [false] for decrypt.
key: function will read 'keybytes' of data as key.
keybytes: MUST be 16(128 bits)/24(256 bits)/32(512 bits).
nonce: the operation 'nonce' for AES_CCM, the IV of AES_GCM.
function will read 'nonce_len' of data as nonce or IV.
nonce_len: the nonce length for AES_CCM, the IV length for AES_GCM.
tag_len: the tag byte length.
payload_len: only valid for AES_CCM, the payload length. Ignore for AES_GCM.
aad_len: only valid for AES_CCM, the aad length. Ignore for AES_GCM.
context: function will use size which return from function
'ali_authenc_get_ctx_size' as internal context. function will check the [status]
of 'context', must be CLEAN or FINISH. function will initialize the [status] of
'context' to INIT. function will save the 'type', 'is_enc', or maybe 'nonce',
'nonce_len', 'tag_len', 'payload_len', 'aad_len' in 'context'. function will
initialize the 'context' to a valid context.
*/
ali_crypto_result ali_authenc_init(authenc_type_t type, bool is_enc,
const uint8_t *key, size_t keybytes,
const uint8_t *nonce, size_t nonce_len,
size_t tag_len,
size_t payload_len, /* valid only in CCM */
size_t aad_len, /* valid only in CCM */
void * context);
/*
aad: the address of aad.
function will read 'aad_size' of data from this address as aad.
aad_size: the length in bytes of aad.
for AES_CCM:
the total summary of 'aad_size' of multiple calling this
function MUST equal to the 'aad_len' parameter in ali_authenc_init. context:
function will use size which return from function 'ali_authenc_get_ctx_size' as
internal context. function will check it is a valid context. function will check
the [status] of 'context', must be INIT or UPDATE_AAD. function will change the
[status] of 'context' to UPDATE_AAD.
*/
ali_crypto_result ali_authenc_update_aad(const uint8_t *aad, size_t aad_size,
void *context);
/*
src: function will read 'size' of data from this area as source data.
MUST be NULL if 'size' is 0
dst: function will write 'size' of data to this area as destination data.
MUST be NULL if 'size' is 0
size: the length of source data, can be any integer or 0.
for AES_CCM.
the total summary of 'size' of multiple calling this function
MUST equal to the 'payload_len' parameter in ali_authenc_init. context: function
will use size which return from function 'ali_authenc_get_ctx_size' as internal
context. function will check it is a valid context. function will check the
[status] of 'context', must be UPDATE_AAD or PROCESS. function will change the
[status] of 'context' to PROCESS. function will do encrypt or decrypt indicated
by the content in 'context'.
*/
ali_crypto_result ali_authenc_process(const uint8_t *src, uint8_t *dst,
size_t size, void *context);
/*
src: function will read 'size' of data from this area as source data.
MUST be NULL if 'src_size' is 0.
src_size: the length of source data.
if 'src_size' == 0, 'src' MUST be NULL, 'dst' MUST be NULL, and this
function will reaturn SUCCESS. dst: function will write certain length
which is retuned by 'dst_size' of data to this area as destination data. MUST be
NULL if 'size' is 0 dst_size: function will wirte some integer to this area to
indicate the length of destination data. tag: the tag returned by ae
encrypt. tag_len: the tag length. context: function will use size which
return from function 'ali_authenc_get_ctx_size' as internal context. function
will check it is a valid context. function will check the [status] of 'context',
must be UPDATE_AAD or PROCESS. function will change the [status] of 'context' to
FINISH. the 'is_enc' indicated by the content in 'context' MUST be ture.
function will do encrypt or decrypt indicated by the content in
'context'. function MUST clean the content of context before this fucntion
return.
*/
ali_crypto_result ali_authenc_enc_finish(const uint8_t *src, size_t src_size,
uint8_t *dst, size_t *dst_size,
uint8_t *tag, size_t *tag_len,
void *context);
/*
src: function will read 'size' of data from this area as source data.
MUST be NULL if 'src_size' is 0.
src_size: the length of source data.
if 'src_size' == 0, 'src' MUST be NULL, 'dst' MUST be NULL, and this
function will reaturn SUCCESS. dst: function will write certain length
which is retuned by 'dst_size' of data to this area as destination data. MUST be
NULL if 'size' is 0 dst_size: function will wirte some integer to this area to
indicate the length of destination data. tag: the tag parameter. function
will read 'tag_len' of data from this address as the decrypt tag. tag_len: the
tag length. context: function will use size which return from function
'ali_authenc_get_ctx_size' as internal context. function will check it is a
valid context. function will check the [status] of 'context', must be UPDATE_AAD
or PROCESS. function will change the [status] of 'context' to FINISH. the
'is_enc' indicated by the content in 'context' MUST be false. function will do
encrypt or decrypt indicated by the content in 'context'. function MUST clean
the content of context before this fucntion return.
*/
ali_crypto_result ali_authenc_dec_finish(const uint8_t *src, size_t src_size,
uint8_t *dst, size_t *dst_size,
const uint8_t *tag, size_t tag_len,
void *context);
ali_crypto_result ali_authenc_reset(void *context);
ali_crypto_result ali_authenc_copy_context(void *dst_ctx, void *src_ctx);
/********************************************************************/
/* HASH */
/********************************************************************/
ali_crypto_result ali_hash_get_ctx_size(hash_type_t type, size_t *size);
ali_crypto_result ali_hash_init(hash_type_t type, void *context);
ali_crypto_result ali_hash_update(const uint8_t *src, size_t size,
void *context);
ali_crypto_result ali_hash_final(uint8_t *dgst, void *context);
ali_crypto_result ali_hash_reset(void *context);
ali_crypto_result ali_hash_copy_context(void *dst_ctx, void *src_ctx);
ali_crypto_result ali_hash_digest(hash_type_t type, const uint8_t *src,
size_t size, uint8_t *dgst);
/********************************************************************/
/* MAC */
/********************************************************************/
/* hmac */
ali_crypto_result ali_hmac_get_ctx_size(hash_type_t type, size_t *size);
ali_crypto_result ali_hmac_init(hash_type_t type, const uint8_t *key,
size_t keybytes, void *context);
ali_crypto_result ali_hmac_update(const uint8_t *src, size_t size,
void *context);
ali_crypto_result ali_hmac_final(uint8_t *dgst, void *context);
ali_crypto_result ali_hmac_reset(void *context);
ali_crypto_result ali_hmac_copy_context(void *dst_ctx, void *src_ctx);
ali_crypto_result ali_hmac_digest(hash_type_t type, const uint8_t *key,
size_t keybytes, const uint8_t *src,
size_t size, uint8_t *dgst);
/* cbcmac */
ali_crypto_result ali_cbcmac_get_ctx_size(cbcmac_type_t type, size_t *size);
ali_crypto_result ali_cbcmac_init(cbcmac_type_t type, const uint8_t *key,
size_t keybytes, void *context);
ali_crypto_result ali_cbcmac_update(const uint8_t *src, size_t size,
void *context);
ali_crypto_result ali_cbcmac_final(sym_padding_t padding, uint8_t *dgst,
void *context);
ali_crypto_result ali_cbcmac_reset(void *context);
ali_crypto_result ali_cbcmac_copy_context(void *dst_ctx, void *src_ctx);
ali_crypto_result ali_cbcmac_digest(cbcmac_type_t type, const uint8_t *key,
size_t keybytes, const uint8_t *src,
size_t size, sym_padding_t padding,
uint8_t *dgst);
/* cmac */
ali_crypto_result ali_cmac_get_ctx_size(cmac_type_t type, size_t *size);
ali_crypto_result ali_cmac_init(cmac_type_t type, const uint8_t *key,
size_t keybytes, void *context);
ali_crypto_result ali_cmac_update(const uint8_t *src, size_t size,
void *context);
ali_crypto_result ali_cmac_final(sym_padding_t padding, uint8_t *dgst,
void *context);
ali_crypto_result ali_cmac_reset(void *context);
ali_crypto_result ali_cmac_copy_context(void *dst_ctx, void *src_ctx);
ali_crypto_result ali_cmac_digest(cmac_type_t type, const uint8_t *key,
size_t keybytes, const uint8_t *src,
size_t size, sym_padding_t padding,
uint8_t *dgst);
/********************************************************************/
/* ASYM */
/********************************************************************/
/* RSA */
/*
* e: Public exponent
* d: Private exponent
* n: Modulus
*
* Optional CRT parameters
* p, q: N = pq
* qp: 1/q mod p
* dp: d mod (p-1)
* dq: d mod (q-1)
*/
/*
* keybits[in]: key length in bits
* size[out]: total size in bytes of rsa keypair
*/
ali_crypto_result ali_rsa_get_keypair_size(size_t keybits, size_t *size);
/*
* keybits[in]: key length in bits
* size[out]: total size in bytes of rsa public key
*/
ali_crypto_result ali_rsa_get_pubkey_size(size_t keybits, size_t *size);
/*
* Initialize RSA keypair
*
* keybits[in]: rsa keypair length in bits
* n/n_size[in]: rsa modulus data and size in bytes
* e/e_size[in]: rsa public exponent data and size in bytes
* d/d_size[in]: rsa private exponent data and size in bytes
* p/p_size[in]: rsa prime1 data and size in bits, may be NULL/0
* q/q_size[in]: rsa prime2 data and size in bits, may be NULL/0
* dp/dp_size[in]: rsa exponent2 data and size in bits, may be NULL/0
* dq/dq_size[in]: rsa exponent2 data and size in bits, may be NULL/0
* dq/dq_size[in]: rsa coefficient data and size in bits, may be NULL/0
* keypair[out]: output buffer, which is used to save initialized rsa key pair
*/
ali_crypto_result ali_rsa_init_keypair(
size_t keybits, const uint8_t *n, size_t n_size, const uint8_t *e,
size_t e_size, const uint8_t *d, size_t d_size, const uint8_t *p,
size_t p_size, const uint8_t *q, size_t q_size, const uint8_t *dp,
size_t dp_size, const uint8_t *dq, size_t dq_size, const uint8_t *qp,
size_t qp_size, rsa_keypair_t *keypair);
/*
* Initialize RSA public key
*
* keybits[in]: rsa key length in bits
* n/n_size[in]: rsa modulus data and size in bytes
* e/e_size[in]: rsa public exponent data and size in bytes
* pubkey[out]: output buffer, which is used to save initialized rsa public
* key
*/
ali_crypto_result ali_rsa_init_pubkey(size_t keybits, const uint8_t *n,
size_t n_size, const uint8_t *e,
size_t e_size, rsa_pubkey_t *pubkey);
/*
* Generate RSA keypair
*
* keybits[in]: rsa key length in bits
* e[in]: optional, public exponent
* e_size[in]: optional, public exponent size in bytes
* keypair[out]: output buffer, which is used to save generated rsa key pair
*/
ali_crypto_result ali_rsa_gen_keypair(size_t keybits, const uint8_t *e,
size_t e_size, rsa_keypair_t *keypair);
/*
* Get key attribute
*
* attr[in]: rsa key attribute ID
* keypair[in]: rsa keypair buffer
* buffer[out]: buffer, which is used to save required attribute
* size[in/out]: buffer max size and key attribute actual size in bytes
*/
ali_crypto_result ali_rsa_get_key_attr(rsa_key_attr_t attr,
rsa_keypair_t *keypair, void *buffer,
size_t *size);
ali_crypto_result ali_rsa_public_encrypt(const rsa_pubkey_t *pub_key,
const uint8_t *src, size_t src_size,
uint8_t *dst, size_t *dst_size,
rsa_padding_t padding);
ali_crypto_result ali_rsa_private_decrypt(const rsa_keypair_t *priv_key,
const uint8_t *src, size_t src_size,
uint8_t *dst, size_t *dst_size,
rsa_padding_t padding);
/*
* dig[in]: the digest to sign
* dig_size[in]: the length of the digest to sign (byte)
* sig[out]: the signature data
* sig_size[in/out]: the buffer size and resulting size of signature
*/
ali_crypto_result ali_rsa_sign(const rsa_keypair_t *priv_key,
const uint8_t *dig, size_t dig_size,
uint8_t *sig, size_t *sig_size,
rsa_padding_t padding);
/*
* dig[in]: the digest of message that was signed
* dig_size[in]: the digest size in bytes
* sig[in]: the signature data
* sig_size[in]: the length of the signature data (byte)
*/
ali_crypto_result ali_rsa_verify(const rsa_pubkey_t *pub_key,
const uint8_t *dig, size_t dig_size,
const uint8_t *sig, size_t sig_size,
rsa_padding_t padding, bool *result);
/* DSA sign/verify */
/*
g: Generator of subgroup (public)
p: Prime number (public)
q: Order of subgroup (public)
y: Public key
x: Private key
*/
ali_crypto_result ali_dsa_get_keypair_size(size_t keybits, size_t *size);
ali_crypto_result ali_dsa_get_pubkey_size(size_t keybits, size_t *size);
ali_crypto_result ali_dsa_init_keypair(size_t keybits, const uint8_t *g,
size_t g_size, const uint8_t *p,
size_t p_size, const uint8_t *q,
size_t q_size, const uint8_t *y,
size_t y_size, const uint8_t *x,
size_t x_size, dsa_keypair_t *keypair);
ali_crypto_result ali_dsa_init_pubkey(size_t keybits, const uint8_t *g,
size_t g_size, const uint8_t *p,
size_t p_size, const uint8_t *q,
size_t q_size, const uint8_t *y,
size_t y_size, dsa_pubkey_t *pubkey);
ali_crypto_result ali_dsa_gen_keypair(size_t keybit, const uint8_t *g,
size_t g_size, const uint8_t *p,
size_t p_size, const uint8_t *q,
size_t q_size, dsa_keypair_t *keypair);
ali_crypto_result ali_dsa_sign(const dsa_keypair_t *priv_key,
const uint8_t *src, size_t src_size,
uint8_t *signature, size_t *sig_size,
dsa_padding_t padding);
ali_crypto_result ali_dsa_verify(const dsa_pubkey_t *pub_key,
const uint8_t *src, size_t src_size,
const uint8_t *signature, size_t sig_size,
dsa_padding_t padding, bool *result);
ali_crypto_result ali_dsa_get_key_attr(dsa_key_attr_t attr,
dsa_keypair_t *keypair, void *buffer,
uint32_t *size);
/* DH derive shared secret */
/*
g: Generator of Z_p
p: Prime modulus
y: Public key
x: Private key
q: Optional
xbits: Optional
*/
ali_crypto_result ali_dh_get_keypair_size(size_t keybits, size_t *size);
ali_crypto_result ali_dh_get_pubkey_size(size_t keybits, size_t *size);
ali_crypto_result ali_dh_init_keypair(size_t keybits, const uint8_t *g,
size_t g_size, const uint8_t *p,
size_t p_size, const uint8_t *y,
size_t y_size, const uint8_t *x,
size_t x_size, const uint8_t *q,
size_t q_size, /* optional */
size_t xbits, /* optional */
dh_keypair_t *keypair);
ali_crypto_result ali_dh_init_pubkey(size_t keybits, const uint8_t *y,
size_t y_size, dh_pubkey_t *pubkey);
ali_crypto_result ali_dh_gen_keypair(size_t keybit, const uint8_t *g,
size_t g_size, const uint8_t *p,
size_t p_size, const uint8_t *q,
size_t q_size, size_t xbits,
dh_keypair_t *keypair);
ali_crypto_result ali_dh_derive_secret(const dh_keypair_t *priv_key,
const dh_pubkey_t * peer_pub_key,
uint8_t * shared_secret,
size_t * secret_size);
ali_crypto_result ali_dh_get_key_attr(dh_key_attr_t attr, dh_keypair_t *keypair,
void *buffer, uint32_t *size);
/*
d: Private value
x: Public value x
y: Public value y
curve: Curve type
*/
ali_crypto_result ali_ecc_get_keypair_size(size_t curve, size_t *size);
ali_crypto_result ali_ecc_get_pubkey_size(size_t curve, size_t *size);
ali_crypto_result ali_ecc_init_keypair(const uint8_t *x, size_t x_size,
const uint8_t *y, size_t y_size,
const uint8_t *d, size_t d_size,
size_t curve, ecc_keypair_t *keypair);
ali_crypto_result ali_ecc_init_pubkey(const uint8_t *x, size_t x_size,
const uint8_t *y, size_t y_size,
size_t curve, ecc_pubkey_t *pubkey);
ali_crypto_result ali_ecc_gen_keypair(size_t curve, ecc_keypair_t *keypair);
/* ECDSA sign/verify */
ali_crypto_result ali_ecdsa_sign(const ecc_keypair_t *priv_key,
const uint8_t *src, size_t src_size,
uint8_t *signature, size_t *sig_size);
ali_crypto_result ali_ecdsa_verify(const ecc_pubkey_t *pub_key,
const uint8_t *src, size_t src_size,
const uint8_t *signature, size_t sig_size,
bool *result);
/* ECDH derive shared secret */
ali_crypto_result ali_ecdh_derive_secret(const ecc_keypair_t *priv_key,
const ecc_pubkey_t * peer_pubkey_key,
uint8_t * shared_secret,
size_t * secret_size);
/* random generator */
ali_crypto_result ali_seed(uint8_t *seed, size_t seed_len);
ali_crypto_result ali_rand_gen(uint8_t *buf, size_t len);
ali_crypto_result ali_crypto_init(void);
void ali_crypto_cleanup(void);
#endif /* _ALI_CRYPTO_H_ */

View file

@ -0,0 +1,28 @@
/**
* Copyright (C) 2017 The YunOS Project. All rights reserved.
*/
#ifndef _ALI_CRYPTO_TYPES_H_
#define _ALI_CRYPTO_TYPES_H_
#include <stdint.h>
#include <stddef.h> /* for size_t */
#include <stdbool.h>
#if 0
typedef unsigned char bool;
#endif
#ifndef false
#define false (0)
#endif
#ifndef true
#define true (1)
#endif
#ifndef NULL
#define NULL ((void *)0)
#endif
#endif /* _ALI_CRYPTO_TYPES_H_ */

View file

@ -0,0 +1,264 @@
#ifndef _CRYPTO_H_
#define _CRYPTO_H_
#include "ali_crypto.h"
#define crypto_aes_get_ctx_size(type, size) ali_aes_get_ctx_size((type), (size))
#define crypto_aes_init(type, is_enc, key1, key2, keybytes, iv, contex) \
ali_aes_init(type, is_enc, key1, key2, keybytes, iv, contex)
#define crypto_aes_process(src, dst, size, context) \
ali_aes_process(src, dst, size, context)
#define crypto_aes_finish(src, src_size, dst, dst_size, padding, context) \
ali_aes_finish(src, src_size, dst, dst_size, padding, context)
#define crypto_aes_reset(context) ali_aes_reset(context)
#define crypto_aes_copy_context(dst_ctx, src_ctx) \
ali_aes_copy_context(dst_ctx, src_ctx)
#define crypto_des_get_ctx_size(type, size) ali_des_get_ctx_size(type, size)
#define crypto_des_init(type, is_enc, key, keybytes, iv, context) \
ali_des_init(type, is_enc, key, keybytes, iv, context)
#define crypto_des_process(src, dst, size, context) \
ali_des_process(src, dst, size, context)
#define crypto_des_finish(src, src_size, dst, dst_size, padding, context) \
ali_des_finish(src, src_size, dst, dst_size, padding, context)
#define crypto_des_reset(context) ali_des_reset(context)
#define crypto_des_copy_context(dst_ctx, src_ctx) \
ali_des_copy_context(dst_ctx, src_ctx)
#define crypto_authenc_get_ctx_size(type, size) \
ali_authenc_get_ctx_size(type, size)
#define crypto_authenc_init(type, is_enc, key, keybytes, nonce, nonce_len, \
tag_len, payload_len, aad_len, context) \
ali_authenc_init(type, is_enc, key, keybytes, nonce, nonce_len, tag_len, \
payload_len, aad_len, context)
#define crypto_authenc_update_aad(aad, aad_size, context) \
ali_authenc_update_aad(aad, aad_size, context)
#define crypto_authenc_process(src, dst, size, context) \
ali_authenc_process(src, dst, size, context)
#define crypto_authenc_enc_finish(src, src_size, dst, dst_size, tag, tag_len, \
context) \
ali_authenc_enc_finish(src, src_size, dst, dst_size, tag, tag_len, context)
#define crypto_authenc_dec_finish(src, src_size, dst, dst_size, tag, tag_len, \
context) \
ali_authenc_dec_finish(src, src_size, dst, dst_size, tag, tag_len, context)
#define crypto_authenc_reset(context) ali_authenc_reset(context)
#define crypto_authenc_copy_context(dst_ctx, src_ctx) \
ali_authenc_copy_context(dst_ctx, src_ctx)
#define crypto_hash_get_ctx_size(type, size) ali_hash_get_ctx_size(type, size)
#define crypto_hash_init(type, context) ali_hash_init(type, context)
#define crypto_hash_update(src, size, context) \
ali_hash_update(src, size, context)
#define crypto_hash_final(dgst, context) ali_hash_final(dgst, context)
#define crypto_hash_reset(context) ali_hash_reset(context)
#define crypto_hash_copy_context(dst_ctx, src_ctx) \
ali_hash_copy_context(dst_ctx, src_ctx)
#define crypto_hash_digest(type, src, size, dgst) \
ali_hash_digest(type, src, size, dgst)
#define crypto_hmac_get_ctx_size(type, size) ali_hmac_get_ctx_size(type, size)
#define crypto_hmac_init(type, key, keybytes, context) \
ali_hmac_init(type, key, keybytes, context)
#define crypto_hmac_update(src, size, context) \
ali_hmac_update(src, size, context)
#define crypto_hmac_final(dgst, context) ali_hmac_final(dgst, context)
#define crypto_hmac_reset(context) ali_hmac_reset(context)
#define crypto_hmac_copy_context(dst_ctx, src_ctx) \
ali_hmac_copy_context(dst_ctx, src_ctx)
#define crypto_hmac_digest(type, key, keybytes, src, size, dgst) \
ali_hmac_digest(type, key, keybytes, src, size, dgst)
#define crypto_cbcmac_get_ctx_size(type, size) \
ali_cbcmac_get_ctx_size(type, size)
#define crypto_cbcmac_init(type, key, keybytes, context) \
ali_cbcmac_init(type, key, keybytes, context)
#define crypto_cbcmac_update(src, size, context) \
ali_cbcmac_update(src, size, context)
#define crypto_cbcmac_final(padding, dgst, context) \
ali_cbcmac_final(padding, dgst, context)
#define crypto_cbcmac_reset(context) ali_cbcmac_reset(context)
#define crypto_cbcmac_copy_context(dst_ctx, src_ctx) \
ali_cbcmac_copy_context(dst_ctx, src_ctx)
#define crypto_cbcmac_digest(type, key, keybytes, src, size, padding, dgst) \
ali_cbcmac_digest(type, key, keybytes, src, size, padding, dgst)
#define crypto_cmac_get_ctx_size(type, size) ali_cmac_get_ctx_size(type, size)
#define crypto_cmac_init(type, key, keybytes, context) \
ali_cmac_init(type, key, keybytes, context)
#define crypto_cmac_update(src, size, context) \
ali_cmac_update(src, size, context)
#define crypto_cmac_final(padding, dgst, context) \
ali_cmac_final(padding, dgst, context)
#define crypto_cmac_reset(context) ali_cmac_reset(context)
#define crypto_cmac_copy_context(dst_ctx, src_ctx) \
ali_cmac_copy_context(dst_ctx, src_ctx)
#define crypto_cmac_digest(type, key, keybytes, src, size, padding, dgst) \
ali_cmac_digest(type, key, keybytes, src, size, padding, dgst)
#define crypto_rsa_get_keypair_size(keybits, size) \
ali_rsa_get_keypair_size(keybits, size)
#define crypto_rsa_get_pubkey_size(keybits, size) \
ali_rsa_get_pubkey_size(keybits, size)
#define crypto_rsa_init_keypair(keybits, n, n_size, e, e_size, d, d_size, p, \
p_size, q, q_size, dp, dp_size, dq, dq_size, \
qp, qp_size, keypair) \
ali_rsa_init_keypair(keybits, n, n_size, e, e_size, d, d_size, p, p_size, \
q, q_size, dp, dp_size, dq, dq_size, qp, qp_size, \
keypair)
#define crypto_rsa_init_pubkey(keybits, n, n_size, e, e_size, pubkey) \
ali_rsa_init_pubkey(keybits, n, n_size, e, e_size, pubkey)
#define crypto_rsa_gen_keypair(keybits, e, e_size, keypair) \
ali_rsa_gen_keypair(keybits, e, e_size, keypair)
#define crypto_rsa_get_key_attr(attr, keypair, buffer, size) \
ali_rsa_get_key_attr(attr, keypair, buffer, size)
#define crypto_rsa_public_encrypt(pub_key, src, src_size, dst, dst_size, \
padding) \
ali_rsa_public_encrypt(pub_key, src, src_size, dst, dst_size, padding)
#define crypto_rsa_private_decrypt(priv_key, src, src_size, dst, dst_size, \
padding) \
ali_rsa_private_decrypt(priv_key, src, src_size, dst, dst_size, padding)
#define crypto_rsa_sign(priv_key, dig, dig_size, sig, sig_size, padding) \
ali_rsa_sign(priv_key, dig, dig_size, sig, sig_size, padding)
#define crypto_rsa_verify(pub_key, dig, dig_size, sig, sig_size, padding, \
result) \
ali_rsa_verify(pub_key, dig, dig_size, sig, sig_size, padding, result)
#define crypto_dsa_get_keypair_size(keybits, size) \
ali_dsa_get_keypair_size(keybits, size)
#define crypto_dsa_get_pubkey_size(keybits, size) \
ali_dsa_get_pubkey_size(keybits, size)
#define crypto_dsa_init_keypair(keybits, g, g_size, p, p_size, q, q_size, y, \
y_size, x, x_size, keypair) \
ali_dsa_init_keypair(keybits, g, g_size, p, p_size, q, q_size, y, y_size, \
x, x_size, keypair)
#define crypto_dsa_init_pubkey(keybits, g, g_size, p, p_size, q, q_size, y, \
y_size, pubkey) \
ali_dsa_init_pubkey(keybits, g, g_size, p, p_size, q, q_size, y, y_size, \
pubkey)
#define crypto_dsa_gen_keypair(keybit, g, g_size, p, p_size, q, q_size, \
keypair) \
ali_dsa_gen_keypair(keybit, g, g_size, p, p_size, q, q_size, keypair)
#define crypto_dsa_sign(priv_key, src, src_size, signature, sig_size, padding) \
ali_dsa_sign(priv_key, src, src_size, signature, sig_size, padding)
#define crypto_dsa_verify(pub_key, src, src_size, signature, sig_size, \
padding, result) \
ali_dsa_verify(pub_key, src, src_size, signature, sig_size, padding, result)
#define crypto_dsa_get_key_attr(attr, keypair, buffer, size) \
ali_dsa_get_key_attr(attr, keypair, buffer, size)
#define crypto_dh_get_keypair_size(keybits, size) \
ali_dh_get_keypair_size(keybits, size)
#define crypto_dh_get_pubkey_size(keybits, size) \
ali_dh_get_pubkey_size(keybits, size)
#define crypto_dh_init_keypair(keybits, g, g_size, p, p_size, y, y_size, x, \
x_size, q, q_size, xbits, keypair) \
ali_dh_init_keypair(keybits, g, g_size, p, p_size, y, y_size, x, x_size, \
q, q_size, xbits, keypair)
#define crypto_dh_init_pubkey(keybits, y, y_size, pubkey) \
ali_dh_init_pubkey(keybits, y, y_size, pubkey)
#define crypto_dh_gen_keypair(keybit, g, g_size, p, p_size, q, q_size, xbits, \
keypair) \
ali_dh_gen_keypair(keybit, g, g_size, p, p_size, q, q_size, xbits, keypair)
#define crypto_dh_derive_secret(priv_key, peer_pub_key, shared_secret, \
secret_size) \
ali_dh_derive_secret(priv_key, peer_pub_key, shared_secret, secret_size)
#define crypto_dh_get_key_attr(attr, keypair, buffer, size) \
ali_dh_get_key_attr(attr, keypair, buffer, size)
#define crypto_ecc_get_keypair_size(curve, size) \
ali_ecc_get_keypair_size(curve, size)
#define crypto_ecc_get_pubkey_size(curve, size) \
ali_ecc_get_pubkey_size(curve, size)
#define crypto_ecc_init_keypair(x, x_size, y, y_size, d, d_size, curve, \
keypair) \
ali_ecc_init_keypair(x, x_size, y, y_size, d, d_size, curve, keypair)
#define crypto_ecc_init_pubkey(x, x_size, y, y_size, curve, pubkey) \
ali_ecc_init_pubkey(x, x_size, y, y_size, curve, pubkey)
#define crypto_ecc_gen_keypair(curve, keypair) \
ali_ecc_gen_keypair(curve, keypair)
#define crypto_ecdsa_sign(priv_key, src, src_size, signature, sig_size) \
ali_ecdsa_sign(priv_key, src, src_size, signature, sig_size)
#define crypto_ecdsa_verify(pub_key, src, src_size, signature, sig_size, \
result) \
ali_ecdsa_verify(pub_key, src, src_size, signature, sig_size, result)
#define crypto_ecdh_derive_secret(priv_key, peer_pubkey_key, shared_secret, \
secret_size) \
ali_ecdh_derive_secret(priv_key, peer_pubkey_key, shared_secret, \
secret_size)
#define crypto_seed(seed, seed_len) ali_seed(seed, seed_len)
#define crypto_rand_gen(buf, len) ali_rand_gen(buf, len)
#define crypto_init() ali_crypto_init()
#define crypto_cleanup() ali_crypto_cleanup()
#endif /* _CRYPTO_H_ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,874 @@
/**
* Copyright (C) 2017 The YunOS Project. All rights reserved.
*/
#include "mbed_crypto.h"
#include "ali_crypto.h"
/* pkcs5 only support 8 bytes block size
* pcks7 support 8,16 bytes block size, so in aes pkcs5 equal pkcs7 */
/*
* output: buf
* output_len: block size
* data_len: cur_data_len */
static void _add_pkcs_padding(unsigned char *output, size_t output_len,
size_t data_len)
{
size_t padding_len = output_len - data_len;
unsigned char i;
for (i = 0; i < padding_len; i++) {
output[data_len + i] = (unsigned char)padding_len;
}
}
static int _get_pkcs_padding(unsigned char *input, size_t input_len,
size_t *data_len)
{
size_t i, pad_idx;
unsigned char padding_len, bad = 0;
if (NULL == input || NULL == data_len) {
return ALI_CRYPTO_INVALID_ARG;
}
padding_len = input[input_len - 1];
*data_len = input_len - padding_len;
/* Avoid logical || since it results in a branch */
bad |= padding_len > input_len;
bad |= padding_len == 0;
/* The number of bytes checked must be independent of padding_len,
* so pick input_len, which is usually 8 or 16 (one block) */
pad_idx = input_len - padding_len;
for (i = 0; i < input_len; i++) {
bad |= (input[i] ^ padding_len) * (i >= pad_idx);
}
return (ALI_CRYPTO_INVALID_PADDING * (bad != 0));
}
static ali_crypto_result _ali_aes_ecb_final(const uint8_t *src, size_t src_size,
uint8_t *dst, size_t *dst_size,
sym_padding_t padding,
aes_ctx_t * ctx)
{
int ret;
uint8_t block[AES_BLOCK_SIZE];
int mode;
size_t round = 0;
size_t data_len;
if (ctx == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_CONTEXT, "ecb_final: invalid context!\n");
}
if (!(padding == SYM_NOPAD || padding == SYM_PKCS5_PAD)) {
/* not support zero padding */
PRINT_RET(ALI_CRYPTO_NOSUPPORT,
"ecb_final: only support no-padding and pkcs5/7!\n");
}
if (padding == SYM_NOPAD) {
if (src == NULL || src_size == 0) {
if (dst_size != NULL) {
*dst_size = 0;
}
return ALI_CRYPTO_SUCCESS;
}
} else if (padding == SYM_PKCS5_PAD) {
/* pkcs5 finish must have input data */
if (NULL == src || 0 == src_size) {
if (dst_size != NULL) {
*dst_size = 0;
}
return ALI_CRYPTO_INVALID_ARG;
}
}
if (dst_size == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG, "ecb_final: invalid arg!\n");
}
if ((0 != *dst_size) && (dst == NULL)) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG, "ecb_final: invalid arg!\n");
}
if (ctx->is_enc) {
mode = MBEDTLS_AES_ENCRYPT;
} else {
mode = MBEDTLS_AES_DECRYPT;
}
if (padding == SYM_NOPAD) {
if (src_size % AES_BLOCK_SIZE != 0) {
PRINT_RET(ALI_CRYPTO_LENGTH_ERR,
"ecb_final: no pad invalid size(%d vs %d)\n",
(int)src_size, (int)*dst_size);
}
if (src_size > *dst_size) {
*dst_size = src_size;
PRINT_RET(ALI_CRYPTO_SHORT_BUFFER,
"ecb_final: no pad short buffer\n");
}
} else if (padding == SYM_PKCS5_PAD) {
if (ctx->is_enc) {
if ((src_size + (AES_BLOCK_SIZE - src_size % AES_BLOCK_SIZE)) >
*dst_size) {
*dst_size =
src_size + (AES_BLOCK_SIZE - src_size % AES_BLOCK_SIZE);
PRINT_RET(ALI_CRYPTO_SHORT_BUFFER,
"ecb_final: enc pkcs short buffer(%d vs %d)\n",
(int)src_size, (int)*dst_size);
}
} else {
if (src_size % AES_BLOCK_SIZE != 0) {
PRINT_RET(ALI_CRYPTO_INVALID_PADDING,
"ecb_final: cipher size is not block align(%d)\n",
(int)src_size);
}
if ((src_size - AES_BLOCK_SIZE) > *dst_size) {
ret = mbedtls_aes_crypt_ecb(
&(ctx->ctx), mode, src + (src_size - AES_BLOCK_SIZE), block);
if (0 != ret) {
PRINT_RET(ALI_CRYPTO_ERROR,
"ecb_final: mbedtls_aes_crypt_ecb fail(%d)\n",
ret);
}
ret = _get_pkcs_padding(block, AES_BLOCK_SIZE, &data_len);
if (0 != ret) {
PRINT_RET(ALI_CRYPTO_ERROR,
"get pkcs padding fail(0x%08x)\n", ret);
}
*dst_size = src_size - (AES_BLOCK_SIZE - data_len);
PRINT_RET(ALI_CRYPTO_SHORT_BUFFER,
"ecb_final: dec pkcs short buffer(%d vs %d)\n",
(int)src_size, (int)*dst_size);
}
}
}
if (MBEDTLS_AES_ENCRYPT == mode) {
/* encrypt */
size_t cur_len;
round = 0;
while (round < (src_size / AES_BLOCK_SIZE)) {
ret = mbedtls_aes_crypt_ecb(&(ctx->ctx), mode,
src + round * AES_BLOCK_SIZE,
dst + round * AES_BLOCK_SIZE);
if (0 != ret) {
PRINT_RET(ALI_CRYPTO_ERROR,
"ecb_final: mbedtls_aes_crypt_ecb fail(%d)\n", ret);
}
round++;
}
cur_len = round * AES_BLOCK_SIZE;
if (padding == SYM_NOPAD) {
if (src_size != cur_len) {
PRINT_RET(ALI_CRYPTO_ERROR,
"ecb_final: src size not block align(%d)\n", cur_len);
}
*dst_size = cur_len;
} else if (padding == SYM_PKCS5_PAD) {
OSA_memcpy(block, src + cur_len, src_size - cur_len);
_add_pkcs_padding(block, AES_BLOCK_SIZE, src_size - cur_len);
ret =
mbedtls_aes_crypt_ecb(&(ctx->ctx), mode, block, dst + cur_len);
if (0 != ret) {
PRINT_RET(ALI_CRYPTO_ERROR,
"ecb_final: mbedtls_aes_crypt_ecb fail(%d)\n", ret);
}
*dst_size = cur_len + AES_BLOCK_SIZE;
}
} else {
/* dencrypt */
uint8_t *tmp_dst = OSA_malloc(src_size);
if (NULL == tmp_dst) {
PRINT_RET(ALI_CRYPTO_OUTOFMEM, "ecb_final: out of memory\n");
}
round = 0;
while (round < (src_size / AES_BLOCK_SIZE)) {
ret = mbedtls_aes_crypt_ecb(&(ctx->ctx), mode,
src + round * AES_BLOCK_SIZE,
tmp_dst + round * AES_BLOCK_SIZE);
if (0 != ret) {
OSA_free(tmp_dst);
PRINT_RET(ALI_CRYPTO_ERROR,
"ecb_final: mbedtls_aes_crypt_ecb fail(%d)\n", ret);
}
round++;
}
if (padding == SYM_NOPAD) {
if (src_size > *dst_size) {
*dst_size = src_size;
OSA_free(tmp_dst);
PRINT_RET(ALI_CRYPTO_SHORT_BUFFER,
"ecb_final: dec no pad short buffer(src size %d vs "
"dst size %d)\n",
src_size, *dst_size);
}
OSA_memcpy(dst, tmp_dst, src_size);
*dst_size = src_size;
} else if (padding == SYM_PKCS5_PAD) {
ret = _get_pkcs_padding(tmp_dst + (round - 1) * AES_BLOCK_SIZE,
AES_BLOCK_SIZE, &data_len);
if (0 != ret) {
OSA_free(tmp_dst);
PRINT_RET(ALI_CRYPTO_ERROR,
"ecb_final: get pkcs padding fail(0x%08x)\n", ret);
}
if (*dst_size < src_size - (AES_BLOCK_SIZE - data_len)) {
OSA_free(tmp_dst);
*dst_size = src_size - (AES_BLOCK_SIZE - data_len);
PRINT_RET(ALI_CRYPTO_SHORT_BUFFER,
"ecb_final: dec pkcs short buffer\n");
}
OSA_memcpy(dst, tmp_dst, src_size - (AES_BLOCK_SIZE - data_len));
*dst_size = src_size - (AES_BLOCK_SIZE - data_len);
}
OSA_free(tmp_dst);
tmp_dst = NULL;
}
return (ali_crypto_result)ret;
}
static ali_crypto_result _ali_aes_cbc_final(const uint8_t *src, size_t src_size,
uint8_t *dst, size_t *dst_size,
sym_padding_t padding,
aes_ctx_t * ctx)
{
int ret;
int mode;
size_t data_len;
uint8_t *tmp_dst = NULL;
if (ctx == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_CONTEXT, "cbc_final: invalid context!\n");
}
if (!(padding == SYM_NOPAD || padding == SYM_PKCS5_PAD)) {
PRINT_RET(ALI_CRYPTO_NOSUPPORT,
"ecb_final: only support no-padding and pkcs5/7!\n");
}
if (padding == SYM_NOPAD) {
if (src == NULL || src_size == 0) {
if (dst_size != NULL) {
*dst_size = 0;
}
return ALI_CRYPTO_SUCCESS;
}
} else if (padding == SYM_PKCS5_PAD) {
/* pkcs5 finish must have input data */
if (NULL == src || 0 == src_size) {
if (dst_size != NULL) {
*dst_size = 0;
}
return ALI_CRYPTO_INVALID_ARG;
}
}
if (dst_size == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG, "cbc_final: invalid arg!\n");
}
if ((0 != *dst_size) && (dst == NULL)) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG, "cbc_final: invalid arg!\n");
}
if (ctx->is_enc) {
mode = MBEDTLS_AES_ENCRYPT;
} else {
mode = MBEDTLS_AES_DECRYPT;
}
if (padding == SYM_NOPAD) {
if (src_size % AES_BLOCK_SIZE != 0) {
PRINT_RET(ALI_CRYPTO_LENGTH_ERR,
"cbc_final: no pad invalid size(%d vs %d)\n",
(int)src_size, (int)*dst_size);
}
if (src_size > *dst_size) {
*dst_size = src_size;
PRINT_RET(ALI_CRYPTO_SHORT_BUFFER, "cbc_final: short buffer\n");
} else {
*dst_size = src_size;
}
} else if (padding == SYM_PKCS5_PAD) {
if (ctx->is_enc) {
if ((src_size + (AES_BLOCK_SIZE - src_size % AES_BLOCK_SIZE)) >
*dst_size) {
*dst_size =
src_size + (AES_BLOCK_SIZE - src_size % AES_BLOCK_SIZE);
PRINT_RET(ALI_CRYPTO_SHORT_BUFFER,
"ecb_final: enc pkcs5 short buffer(%d vs %d)\n",
(int)src_size, (int)*dst_size);
}
} else {
if (src_size % AES_BLOCK_SIZE != 0) {
PRINT_RET(ALI_CRYPTO_INVALID_PADDING,
"cbc_final: cipher size is not block align(%d)\n",
(int)src_size);
}
if ((src_size - AES_BLOCK_SIZE) > *dst_size) {
tmp_dst = OSA_malloc(src_size);
if (NULL == tmp_dst) {
PRINT_RET(ALI_CRYPTO_OUTOFMEM,
"cbc_final: out of memory\n");
}
ret =
mbedtls_aes_crypt_cbc(&(ctx->ctx), mode, src_size,
(unsigned char *)ctx->iv, src, tmp_dst);
if (0 != ret) {
OSA_free(tmp_dst);
PRINT_RET(ALI_CRYPTO_ERROR,
"cbc_final: mbedtls_aes_crypt_cbc fail(%d)\n",
ret);
}
ret = _get_pkcs_padding(tmp_dst + src_size - AES_BLOCK_SIZE,
AES_BLOCK_SIZE, &data_len);
if (0 != ret) {
OSA_free(tmp_dst);
PRINT_RET(ALI_CRYPTO_ERROR,
"cbc_final: get pkcs padding fail(0x%08x)\n",
ret);
}
*dst_size = src_size - (AES_BLOCK_SIZE - data_len);
OSA_free(tmp_dst);
tmp_dst = NULL;
PRINT_RET(ALI_CRYPTO_SHORT_BUFFER,
"cbc_final: dec pkcs short buffer(%d vs %d)\n",
(int)src_size, (int)*dst_size);
}
}
}
if (MBEDTLS_AES_ENCRYPT == mode) {
/* encrypt, short buffer will be blocked above */
size_t cur_len;
uint8_t block[AES_BLOCK_SIZE];
cur_len = src_size & (~(AES_BLOCK_SIZE - 1));
ret = mbedtls_aes_crypt_cbc(
&(ctx->ctx), mode, cur_len, (unsigned char *)ctx->iv,
(const unsigned char *)src, (unsigned char *)dst);
if (0 != ret) {
PRINT_RET(ALI_CRYPTO_ERROR,
"cbc_final: mbedtls_aes_crypt_cbc fail(%d)\n", ret);
}
if (padding == SYM_PKCS5_PAD) {
OSA_memcpy(block, src + cur_len, src_size - cur_len);
_add_pkcs_padding(block, AES_BLOCK_SIZE, src_size - cur_len);
ret = mbedtls_aes_crypt_cbc(
&(ctx->ctx), mode, AES_BLOCK_SIZE, (unsigned char *)ctx->iv,
(const unsigned char *)block, (unsigned char *)(dst + cur_len));
if (0 != ret) {
PRINT_RET(ALI_CRYPTO_ERROR,
"cbc_final: mbedtls_aes_crypt_cbc fail(%d)\n", ret);
}
*dst_size = cur_len + AES_BLOCK_SIZE;
}
} else {
/* dencrypt */
if (padding == SYM_NOPAD) {
ret = mbedtls_aes_crypt_cbc(
&(ctx->ctx), mode, src_size, (unsigned char *)ctx->iv,
(const unsigned char *)src, (unsigned char *)dst);
if (0 != ret) {
PRINT_RET(ALI_CRYPTO_ERROR,
"cbc_final: mbedtls_aes_crypt_cbc fail(%d)\n", ret);
}
*dst_size = src_size;
} else if (padding == SYM_PKCS5_PAD) {
/* avoid dst size is not enougth */
tmp_dst = OSA_malloc(src_size);
if (NULL == tmp_dst) {
PRINT_RET(ALI_CRYPTO_ERROR, "cbc_final: out of memory\n");
}
ret = mbedtls_aes_crypt_cbc(
&(ctx->ctx), mode, src_size, (unsigned char *)ctx->iv,
(const unsigned char *)src, (unsigned char *)tmp_dst);
if (0 != ret) {
OSA_free(tmp_dst);
PRINT_RET(ALI_CRYPTO_ERROR,
"cbc_final: mbedtls_aes_crypt_cbc fail(%d)\n", ret);
}
ret = _get_pkcs_padding(tmp_dst + src_size - AES_BLOCK_SIZE,
AES_BLOCK_SIZE, &data_len);
if (0 != ret) {
OSA_free(tmp_dst);
PRINT_RET(ALI_CRYPTO_ERROR,
"cbc_final: get pkcs padding fail(0x%08x)\n", ret);
}
if (*dst_size < src_size - (AES_BLOCK_SIZE - data_len)) {
OSA_free(tmp_dst);
*dst_size = src_size - (AES_BLOCK_SIZE - data_len);
PRINT_RET(ALI_CRYPTO_SHORT_BUFFER,
"cbc_final: dec pkcs short buffer\n");
}
OSA_memcpy(dst, tmp_dst, src_size - (AES_BLOCK_SIZE - data_len));
*dst_size = src_size - (AES_BLOCK_SIZE - data_len);
OSA_free(tmp_dst);
}
}
return (ali_crypto_result)ret;
}
static ali_crypto_result _ali_aes_ctr_final(const uint8_t *src, size_t src_size,
uint8_t *dst, size_t *dst_size,
aes_ctx_t *ctx)
{
int ret;
if (ctx == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_CONTEXT, "ctr_final: invalid context!\n");
}
if (src == NULL || src_size == 0) {
if (dst_size != NULL) {
*dst_size = 0;
}
return ALI_CRYPTO_SUCCESS;
}
if (dst_size == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG, "ctr_final: invalid arg!\n");
}
if (src_size > *dst_size) {
*dst_size = src_size;
PRINT_RET(ALI_CRYPTO_SHORT_BUFFER,
"ctr_final: short buffer(%d vs %d)\n", (int)src_size,
(int)*dst_size);
}
ret = mbedtls_aes_crypt_ctr(
&(ctx->ctx), src_size, &(ctx->offset), (unsigned char *)ctx->iv,
(unsigned char *)ctx->stream_block, (const unsigned char *)src,
(unsigned char *)dst);
*dst_size = src_size;
return (ali_crypto_result)ret;
}
#if defined(MBEDTLS_CIPHER_MODE_CFB)
static ali_crypto_result _ali_aes_cfb_final(const uint8_t *src, size_t src_size,
uint8_t *dst, size_t *dst_size,
aes_ctx_t *ctx)
{
int ret;
int mode;
if (ctx == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_CONTEXT, "cfb_final: invalid context!\n");
}
if (src == NULL || src_size == 0) {
if (dst_size != NULL) {
*dst_size = 0;
}
return ALI_CRYPTO_SUCCESS;
}
if (dst == NULL || dst_size == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG, "cfb_final: invalid arg!\n");
}
if (src_size > *dst_size) {
*dst_size = src_size;
PRINT_RET(ALI_CRYPTO_SHORT_BUFFER,
"cfb_final: short buffer(%d vs %d)\n", (int)src_size,
(int)*dst_size);
}
if (ctx->is_enc) {
mode = MBEDTLS_AES_ENCRYPT;
} else {
mode = MBEDTLS_AES_DECRYPT;
}
if (ctx->type == AES_CFB8) {
ret = mbedtls_aes_crypt_cfb8(
&(ctx->ctx), mode, src_size, (unsigned char *)ctx->iv,
(const unsigned char *)src, (unsigned char *)dst);
} else if (ctx->type == AES_CFB128) {
ret = mbedtls_aes_crypt_cfb128(
&(ctx->ctx), mode, src_size, &(ctx->offset), (unsigned char *)ctx->iv,
(const unsigned char *)src, (unsigned char *)dst);
} else {
PRINT_RET(ALI_CRYPTO_INVALID_ARG, "cfb_final: invalid cfb type!\n");
}
*dst_size = src_size;
return (ali_crypto_result)ret;
}
#endif
ali_crypto_result ali_aes_get_ctx_size(aes_type_t type, size_t *size)
{
if (size == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG, "aes_get_ctx_size: bad input!\n");
}
switch (type) {
case AES_ECB:
case AES_CBC:
case AES_CTR:
#if defined(MBEDTLS_CIPHER_MODE_CFB)
case AES_CFB8:
case AES_CFB128:
#endif
break;
case AES_CTS:
case AES_XTS:
PRINT_RET(ALI_CRYPTO_NOSUPPORT,
"ali_aes_init: invalid aes type(%d)\n", type);
default:
PRINT_RET(ALI_CRYPTO_INVALID_TYPE,
"ali_aes_init: invalid aes type(%d)\n", type);
}
*size = sizeof(aes_ctx_t);
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_aes_init(aes_type_t type, bool is_enc,
const uint8_t *key1, const uint8_t *key2,
size_t keybytes, const uint8_t *iv,
void *context)
{
int ret = ALI_CRYPTO_SUCCESS;
aes_ctx_t *aes_ctx;
(void)key2;
if (key1 == NULL || context == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG, "ali_aes_init: bad input args!\n");
}
if (keybytes != 16 && keybytes != 24 && keybytes != 32) {
PRINT_RET(ALI_CRYPTO_LENGTH_ERR, "ali_aes_init: bad key lenth(%d)\n",
(int)keybytes);
}
aes_ctx = (aes_ctx_t *)context;
if ((IS_VALID_CTX_MAGIC(aes_ctx->magic) &&
aes_ctx->status != CRYPTO_STATUS_FINISHED) &&
aes_ctx->status != CRYPTO_STATUS_CLEAN) {
PRINT_RET(ALI_CRYPTO_ERR_STATE, "ali_aes_init: bad status(%d)\n",
(int)aes_ctx->status);
}
switch (type) {
case AES_ECB:
break;
case AES_CBC: {
if (iv == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG,
"ali_aes_init: cbc iv is null\n");
}
OSA_memcpy(aes_ctx->iv, iv, 16);
break;
}
case AES_CTR: {
if (iv == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG,
"ali_aes_init: ctr iv is null\n");
}
OSA_memcpy(aes_ctx->iv, iv, 16);
break;
}
#if defined(MBEDTLS_CIPHER_MODE_CFB)
case AES_CFB8:
case AES_CFB128: {
if (iv == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG,
"ali_aes_init: cfb iv is null\n");
}
OSA_memcpy(aes_ctx->iv, iv, 16);
break;
}
#endif
case AES_CTS:
case AES_XTS:
PRINT_RET(ALI_CRYPTO_NOSUPPORT,
"ali_aes_init: not support aes type(%d)\n", type);
break;
default:
PRINT_RET(ALI_CRYPTO_INVALID_TYPE,
"ali_aes_init: invalid aes type(%d)\n", type);
}
mbedtls_aes_init(&(aes_ctx->ctx));
aes_ctx->is_enc = is_enc;
if (aes_ctx->is_enc) {
ret = mbedtls_aes_setkey_enc(&(aes_ctx->ctx), key1, keybytes * 8);
} else {
if (AES_CTR == type || AES_CFB8 == type || AES_CFB128 == type) {
ret = mbedtls_aes_setkey_enc(&(aes_ctx->ctx), key1, keybytes * 8);
} else {
ret = mbedtls_aes_setkey_dec(&(aes_ctx->ctx), key1, keybytes * 8);
}
}
if (ret != ALI_CRYPTO_SUCCESS) {
PRINT_RET(ALI_CRYPTO_ERROR, "ALI_aes_init: start mode(%d) fail(%d)\n",
type, ret);
}
aes_ctx->offset = 0;
aes_ctx->type = type;
aes_ctx->status = CRYPTO_STATUS_INITIALIZED;
INIT_CTX_MAGIC(aes_ctx->magic);
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_aes_process(const uint8_t *src, uint8_t *dst, size_t size,
void *context)
{
int ret;
aes_ctx_t *aes_ctx;
int mode;
if (context == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_CONTEXT, "ali_aes_process: bad ctx!\n");
}
if (src == NULL || dst == NULL || size == 0) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG, "ali_aes_process: bad args!\n");
}
aes_ctx = (aes_ctx_t *)context;
if (!IS_VALID_CTX_MAGIC(aes_ctx->magic)) {
PRINT_RET(ALI_CRYPTO_INVALID_CONTEXT, "ali_aes_process: bad magic!\n");
}
if ((aes_ctx->status != CRYPTO_STATUS_INITIALIZED) &&
(aes_ctx->status != CRYPTO_STATUS_PROCESSING)) {
PRINT_RET(ALI_CRYPTO_ERR_STATE, "ali_aes_update: bad status(%d)\n",
(int)aes_ctx->status);
}
if (aes_ctx->is_enc) {
mode = MBEDTLS_AES_ENCRYPT;
} else {
mode = MBEDTLS_AES_DECRYPT;
}
switch (aes_ctx->type) {
/* FIXME, limitation, size must be block size aigned */
case AES_ECB: {
size_t cur_len = 0;
if (size % AES_BLOCK_SIZE != 0) {
PRINT_RET(ALI_CRYPTO_LENGTH_ERR,
"ali_aes_process: invalid size(%d)\n", (int)size);
}
while (cur_len < size) {
ret = mbedtls_aes_crypt_ecb(&(aes_ctx->ctx), mode,
src + cur_len, dst + cur_len);
if (0 != ret) {
PRINT_RET(ALI_CRYPTO_ERROR,
"mbedtls_aes_crypt_ecb fail(%d)\n", ret);
}
cur_len += AES_BLOCK_SIZE;
}
break;
}
case AES_CBC: {
if (size % AES_BLOCK_SIZE != 0) {
PRINT_RET(ALI_CRYPTO_LENGTH_ERR,
"ali_aes_process: invalid size(%d)\n", (int)size);
}
ret = mbedtls_aes_crypt_cbc(
&(aes_ctx->ctx), mode, size, (unsigned char *)aes_ctx->iv,
(const unsigned char *)src, (unsigned char *)dst);
#if 0 /* mbedtls have copy it */
if (ret == ALI_CRYPTO_SUCCESS) {
OSA_memcpy(aes_ctx->iv, src - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
}
#endif
break;
}
case AES_CTR: {
ret = mbedtls_aes_crypt_ctr(
&(aes_ctx->ctx), size, &(aes_ctx->offset),
(unsigned char *)aes_ctx->iv,
(unsigned char *)aes_ctx->stream_block,
(const unsigned char *)src, (unsigned char *)dst);
break;
}
#if defined(MBEDTLS_CIPHER_MODE_CFB)
case AES_CFB8: {
ret = mbedtls_aes_crypt_cfb8(
&(aes_ctx->ctx), mode, size, (unsigned char *)aes_ctx->iv,
(const unsigned char *)src, (unsigned char *)dst);
break;
}
case AES_CFB128: {
ret = mbedtls_aes_crypt_cfb128(
&(aes_ctx->ctx), mode, size, &(aes_ctx->offset),
(unsigned char *)aes_ctx->iv, (const unsigned char *)src,
(unsigned char *)dst);
break;
}
#endif
case AES_CTS:
case AES_XTS:
default:
PRINT_RET(ALI_CRYPTO_NOSUPPORT,
"ali_aes_process: invalid hash type(%d)\n",
aes_ctx->type);
}
if (ret != ALI_CRYPTO_SUCCESS) {
if (aes_ctx->is_enc) {
MBED_DBG_E("ali_aes_process: encrypt(%d) fail!\n", aes_ctx->type);
} else {
MBED_DBG_E("ali_aes_process: decrypt(%d) fail!\n", aes_ctx->type);
}
return ALI_CRYPTO_ERROR;
}
aes_ctx->status = CRYPTO_STATUS_PROCESSING;
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_aes_finish(const uint8_t *src, size_t src_size,
uint8_t *dst, size_t *dst_size,
sym_padding_t padding, void *context)
{
ali_crypto_result ret;
aes_ctx_t * aes_ctx;
if ((src == NULL && src_size != 0) ||
((dst_size != NULL) && (dst == NULL && *dst_size != 0)) ||
context == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG, "ali_aes_finish: bad input args!\n");
}
aes_ctx = (aes_ctx_t *)context;
if (!IS_VALID_CTX_MAGIC(aes_ctx->magic)) {
PRINT_RET(ALI_CRYPTO_INVALID_CONTEXT, "ali_aes_finish: bad magic!\n");
}
if ((aes_ctx->status != CRYPTO_STATUS_INITIALIZED) &&
(aes_ctx->status != CRYPTO_STATUS_PROCESSING)) {
PRINT_RET(ALI_CRYPTO_ERR_STATE, "ali_aes_finish: bad status(%d)\n",
(int)aes_ctx->status);
}
switch (aes_ctx->type) {
case AES_ECB: {
ret = _ali_aes_ecb_final(src, src_size, dst, dst_size, padding,
aes_ctx);
break;
}
case AES_CBC: {
ret = _ali_aes_cbc_final(src, src_size, dst, dst_size, padding,
aes_ctx);
break;
}
case AES_CTR: {
ret = _ali_aes_ctr_final(src, src_size, dst, dst_size, aes_ctx);
break;
}
#if defined(MBEDTLS_CIPHER_MODE_CFB)
case AES_CFB8:
case AES_CFB128: {
ret = _ali_aes_cfb_final(src, src_size, dst, dst_size, aes_ctx);
break;
}
#endif
case AES_CTS:
case AES_XTS:
default:
PRINT_RET(ALI_CRYPTO_NOSUPPORT,
"ali_aes_finish: invalid aes type(%d)\n", aes_ctx->type);
}
if (ret != ALI_CRYPTO_SUCCESS) {
mbedtls_aes_free(&(aes_ctx->ctx));
PRINT_RET(ret, "ali_aes_process: aes type(%d) final fail(%08x)\n",
aes_ctx->type, ret);
}
CLEAN_CTX_MAGIC(aes_ctx->magic);
aes_ctx->status = CRYPTO_STATUS_FINISHED;
aes_ctx->offset = 0;
mbedtls_aes_free(&(aes_ctx->ctx));
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_aes_reset(void *context)
{
aes_ctx_t *aes_ctx;
if (context == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG, "ali_aes_reset: bad input args!\n");
}
aes_ctx = (aes_ctx_t *)context;
#if 0
if (!IS_VALID_CTX_MAGIC(aes_ctx->magic)) {
PRINT_RET(ALI_CRYPTO_INVALID_CONTEXT, "ali_aes_reset: bad magic!\n");
}
#endif
OSA_memset(aes_ctx, 0, sizeof(aes_ctx_t));
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_aes_copy_context(void *dst_ctx, void *src_ctx)
{
aes_ctx_t *aes_ctx_src, *aes_ctx_dst;
if ((dst_ctx == NULL) || (src_ctx == NULL)) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG,
"ali_aes_copy_context: bad input args!\n");
}
aes_ctx_src = (aes_ctx_t *)src_ctx;
if (!IS_VALID_CTX_MAGIC(aes_ctx_src->magic)) {
PRINT_RET(ALI_CRYPTO_INVALID_CONTEXT,
"ali_aes_copy_context: bad magic!\n");
}
/* only can copy to one un-initialized context */
aes_ctx_dst = (aes_ctx_t *)dst_ctx;
if ((IS_VALID_CTX_MAGIC(aes_ctx_dst->magic)) &&
((aes_ctx_dst->status == CRYPTO_STATUS_INITIALIZED) ||
(aes_ctx_dst->status == CRYPTO_STATUS_PROCESSING) ||
(aes_ctx_dst->status == CRYPTO_STATUS_FINISHED))) {
PRINT_RET(ALI_CRYPTO_ERR_STATE, "ali_aes_init: bad dst status(%d)\n",
(int)aes_ctx_dst->status);
}
OSA_memcpy(aes_ctx_dst, aes_ctx_src, sizeof(aes_ctx_t));
return ALI_CRYPTO_SUCCESS;
}

View file

@ -0,0 +1,56 @@
/**
* Copyright (C) 2016 The YunOS Project. All rights reserved.
*/
#include "ali_crypto.h"
ali_crypto_result ali_ecc_get_keypair_size(size_t curve, size_t *size)
{
return ALI_CRYPTO_NOSUPPORT;
}
ali_crypto_result ali_ecc_get_pubkey_size(size_t curve, size_t *size)
{
return ALI_CRYPTO_NOSUPPORT;
}
ali_crypto_result ali_ecc_init_keypair(
const uint8_t *x, size_t x_size,
const uint8_t *y, size_t y_size,
const uint8_t *d, size_t d_size,
size_t curve, ecc_keypair_t *keypair)
{
return ALI_CRYPTO_NOSUPPORT;
}
ali_crypto_result ali_ecc_init_pubkey(
const uint8_t *x, size_t x_size,
const uint8_t *y, size_t y_size,
size_t curve, ecc_pubkey_t *pubkey)
{
return ALI_CRYPTO_NOSUPPORT;
}
ali_crypto_result ali_ecc_gen_keypair(
size_t curve, ecc_keypair_t *keypair)
{
return ALI_CRYPTO_NOSUPPORT;
}
ali_crypto_result ali_ecdsa_sign(const ecc_keypair_t *priv_key,
const uint8_t *src, size_t src_size,
uint8_t *signature, size_t *sig_size)
{
return ALI_CRYPTO_NOSUPPORT;
}
ali_crypto_result ali_ecdsa_verify(const ecc_pubkey_t *pub_key,
const uint8_t *src, size_t src_size,
const uint8_t *signature, size_t sig_size,
bool *result)
{
return ALI_CRYPTO_NOSUPPORT;
}
ali_crypto_result ali_ecdh_derive_secret(
const ecc_keypair_t *priv_key,
const ecc_pubkey_t *peer_pubkey_key,
uint8_t *shared_secret, size_t *secret_size)
{
return ALI_CRYPTO_NOSUPPORT;
}

View file

@ -0,0 +1,401 @@
/**
* Copyright (C) 2017 The YunOS Project. All rights reserved.
*/
#include "mbed_crypto.h"
#include "ali_crypto.h"
ali_crypto_result ali_hash_get_ctx_size(hash_type_t type, size_t *size)
{
if (NULL == size) {
MBED_DBG_E("get_ctx_size: bad input!\n");
return ALI_CRYPTO_INVALID_ARG;
}
switch(type) {
case SHA1:
case SHA224:
case SHA256:
case SHA384:
case SHA512:
case MD5:
break;
default:
MBED_DBG_E("get_ctx_size: invalid hash type(%d)\n", type);
return ALI_CRYPTO_INVALID_TYPE;
}
*size = sizeof(hash_ctx_t);
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_hash_init(hash_type_t type, void *context)
{
hash_ctx_t *hash_ctx;
if (NULL == context) {
MBED_DBG_E("ali_hash_init: bad ctx!\n");
return ALI_CRYPTO_INVALID_CONTEXT;
}
hash_ctx = (hash_ctx_t *)context;
if ((IS_VALID_CTX_MAGIC(hash_ctx->magic) &&
hash_ctx->status != CRYPTO_STATUS_FINISHED) &&
hash_ctx->status != CRYPTO_STATUS_CLEAN) {
MBED_DBG_E("ali_hash_init: bad status(%d)\n", (int)hash_ctx->status);
return ALI_CRYPTO_ERR_STATE;
}
switch(type) {
#ifdef MBEDTLS_SHA1_C
case SHA1: {
mbedtls_sha1_init(&hash_ctx->sha1_ctx);
mbedtls_sha1_starts(&hash_ctx->sha1_ctx);
break;
}
#endif
#ifdef MBEDTLS_SHA256_C
case SHA224: {
mbedtls_sha256_init(&hash_ctx->sha256_ctx);
mbedtls_sha256_starts(&hash_ctx->sha256_ctx, 1);
break;
}
case SHA256: {
mbedtls_sha256_init(&hash_ctx->sha256_ctx);
mbedtls_sha256_starts(&hash_ctx->sha256_ctx, 0);
break;
}
#endif
#ifdef MBEDTLS_SHA512_C
case SHA384: {
mbedtls_sha512_init(&hash_ctx->sha512_ctx);
mbedtls_sha512_starts(&hash_ctx->sha512_ctx, 1);
break;
}
case SHA512: {
mbedtls_sha512_init(&hash_ctx->sha512_ctx);
mbedtls_sha512_starts(&hash_ctx->sha512_ctx, 0);
break;
}
#endif
#ifdef MBEDTLS_MD5_C
case MD5: {
mbedtls_md5_init(&hash_ctx->md5_ctx);
mbedtls_md5_starts(&hash_ctx->md5_ctx);
break;
}
#endif
default:
MBED_DBG_E("ali_hash_init: invalid hash type(%d)\n", type);
return ALI_CRYPTO_INVALID_TYPE;
}
hash_ctx->type = type;
hash_ctx->status = CRYPTO_STATUS_INITIALIZED;
INIT_CTX_MAGIC(hash_ctx->magic);
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_hash_update(const uint8_t *src, size_t size, void *context)
{
hash_ctx_t *hash_ctx;
if (context == NULL) {
MBED_DBG_E("ali_hash_update: bad ctx!\n");
return ALI_CRYPTO_INVALID_CONTEXT;
}
if (src == NULL && size != 0) {
MBED_DBG_E("ali_hash_update: bad args!\n");
return ALI_CRYPTO_INVALID_ARG;
}
hash_ctx = (hash_ctx_t *)context;
if (!IS_VALID_CTX_MAGIC(hash_ctx->magic)) {
MBED_DBG_E("ali_hash_update: bad magic!\n");
return ALI_CRYPTO_INVALID_CONTEXT;
}
if ((hash_ctx->status != CRYPTO_STATUS_INITIALIZED) &&
(hash_ctx->status != CRYPTO_STATUS_PROCESSING)) {
MBED_DBG_E("ali_hash_update: bad status(%d)\n", (int)hash_ctx->status);
return ALI_CRYPTO_ERR_STATE;
}
switch(hash_ctx->type) {
#ifdef MBEDTLS_SHA1_C
case SHA1: {
mbedtls_sha1_update(&hash_ctx->sha1_ctx,
(const unsigned char *)src, size);
break;
}
#endif
#ifdef MBEDTLS_SHA256_C
case SHA224: {
mbedtls_sha256_update(&hash_ctx->sha256_ctx,
(const unsigned char *)src, size);
break;
}
case SHA256: {
mbedtls_sha256_update(&hash_ctx->sha256_ctx,
(const unsigned char *)src, size);
break;
}
#endif
#ifdef MBEDTLS_SHA512_C
case SHA384: {
mbedtls_sha512_update(&hash_ctx->sha512_ctx,
(const unsigned char *)src, size);
break;
}
case SHA512: {
mbedtls_sha512_update(&hash_ctx->sha512_ctx,
(const unsigned char *)src, size);
break;
}
#endif
#ifdef MBEDTLS_MD5_C
case MD5: {
mbedtls_md5_update(&hash_ctx->md5_ctx,
(const unsigned char *)src, size);
break;
}
#endif
default:
MBED_DBG_E("ali_hash_update: invalid hash type(%d)\n", hash_ctx->type);
return ALI_CRYPTO_INVALID_TYPE;
}
hash_ctx->status = CRYPTO_STATUS_PROCESSING;
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_hash_final(uint8_t *dgst, void *context)
{
hash_ctx_t *hash_ctx;
if (context == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_CONTEXT, "ali_hash_final: invalid context!\n");
}
if (dgst == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG, "ali_hash_final: bad input args!\n");
}
hash_ctx = (hash_ctx_t *)context;
if (!IS_VALID_CTX_MAGIC(hash_ctx->magic)) {
MBED_DBG_E("ali_hash_final: bad magic!\n");
return ALI_CRYPTO_INVALID_CONTEXT;
}
if ((hash_ctx->status != CRYPTO_STATUS_INITIALIZED) &&
(hash_ctx->status != CRYPTO_STATUS_PROCESSING)) {
MBED_DBG_E("ali_hash_final: bad status(%d)\n", (int)hash_ctx->status);
return ALI_CRYPTO_ERR_STATE;
}
switch(hash_ctx->type) {
#ifdef MBEDTLS_SHA1_C
case SHA1: {
mbedtls_sha1_finish(&hash_ctx->sha1_ctx, (unsigned char *)dgst);
mbedtls_sha1_free(&hash_ctx->sha1_ctx);
break;
}
#endif
#ifdef MBEDTLS_SHA256_C
case SHA224: {
mbedtls_sha256_finish(&hash_ctx->sha256_ctx, (unsigned char *)dgst);
mbedtls_sha256_free(&hash_ctx->sha256_ctx);
break;
}
case SHA256: {
mbedtls_sha256_finish(&hash_ctx->sha256_ctx, (unsigned char *)dgst);
mbedtls_sha256_free(&hash_ctx->sha256_ctx);
break;
}
#endif
#ifdef MBEDTLS_SHA512_C
case SHA384: {
mbedtls_sha512_finish(&hash_ctx->sha512_ctx, (unsigned char *)dgst);
mbedtls_sha512_free(&hash_ctx->sha512_ctx);
break;
}
case SHA512: {
mbedtls_sha512_finish(&hash_ctx->sha512_ctx, (unsigned char *)dgst);
mbedtls_sha512_free(&hash_ctx->sha512_ctx);
break;
}
#endif
#ifdef MBEDTLS_MD5_C
case MD5: {
mbedtls_md5_finish(&hash_ctx->md5_ctx, (unsigned char *)dgst);
mbedtls_md5_free(&hash_ctx->md5_ctx);
break;
}
#endif
default:
MBED_DBG_E("ali_hash_final: invalid hash type(%d)\n", hash_ctx->type);
return ALI_CRYPTO_INVALID_TYPE;
}
CLEAN_CTX_MAGIC(hash_ctx->magic);
hash_ctx->status = CRYPTO_STATUS_FINISHED;
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_hash_digest(hash_type_t type,
const uint8_t *src, size_t size, uint8_t *dgst)
{
hash_ctx_t hash_ctx;
if ((src == NULL && size != 0) || dgst == NULL) {
MBED_DBG_E("ali_hash_digest: bad input args!\n");
return ALI_CRYPTO_INVALID_ARG;
}
switch(type) {
#ifdef MBEDTLS_SHA1_C
case SHA1: {
mbedtls_sha1_init(&hash_ctx.sha1_ctx);
mbedtls_sha1_starts(&hash_ctx.sha1_ctx);
mbedtls_sha1_update(&hash_ctx.sha1_ctx,
(const unsigned char *)src, size);
mbedtls_sha1_finish(&hash_ctx.sha1_ctx, (unsigned char *)dgst);
mbedtls_sha1_free(&hash_ctx.sha1_ctx);
break;
}
#endif
#ifdef MBEDTLS_SHA256_C
case SHA224: {
mbedtls_sha256_init(&hash_ctx.sha256_ctx);
mbedtls_sha256_starts(&hash_ctx.sha256_ctx, 1);
mbedtls_sha256_update(&hash_ctx.sha256_ctx,
(const unsigned char *)src, size);
mbedtls_sha256_finish(&hash_ctx.sha256_ctx, (unsigned char *)dgst);
mbedtls_sha256_free(&hash_ctx.sha256_ctx);
break;
}
case SHA256: {
mbedtls_sha256_init(&hash_ctx.sha256_ctx);
mbedtls_sha256_starts(&hash_ctx.sha256_ctx, 0);
mbedtls_sha256_update(&hash_ctx.sha256_ctx,
(const unsigned char *)src, size);
mbedtls_sha256_finish(&hash_ctx.sha256_ctx, (unsigned char *)dgst);
mbedtls_sha256_free(&hash_ctx.sha256_ctx);
break;
}
#endif
#ifdef MBEDTLS_SHA512_C
case SHA384: {
mbedtls_sha512_init(&hash_ctx.sha512_ctx);
mbedtls_sha512_starts(&hash_ctx.sha512_ctx, 1);
mbedtls_sha512_update(&hash_ctx.sha512_ctx,
(const unsigned char *)src, size);
mbedtls_sha512_finish(&hash_ctx.sha512_ctx, (unsigned char *)dgst);
mbedtls_sha512_free(&hash_ctx.sha512_ctx);
break;
}
case SHA512: {
mbedtls_sha512_init(&hash_ctx.sha512_ctx);
mbedtls_sha512_starts(&hash_ctx.sha512_ctx, 0);
mbedtls_sha512_update(&hash_ctx.sha512_ctx,
(const unsigned char *)src, size);
mbedtls_sha512_finish(&hash_ctx.sha512_ctx, (unsigned char *)dgst);
mbedtls_sha512_free(&hash_ctx.sha512_ctx);
break;
}
#endif
#ifdef MBEDTLS_MD5_C
case MD5: {
mbedtls_md5_init(&hash_ctx.md5_ctx);
mbedtls_md5_starts(&hash_ctx.md5_ctx);
mbedtls_md5_update(&hash_ctx.md5_ctx,
(const unsigned char *)src, size);
mbedtls_md5_finish(&hash_ctx.md5_ctx, (unsigned char *)dgst);
mbedtls_md5_free(&hash_ctx.md5_ctx);
break;
}
#endif
default:
MBED_DBG_E("ali_hash_digest: invalid hash type(%d)\n", type);
return ALI_CRYPTO_INVALID_TYPE;
}
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_hash_reset(void *context)
{
hash_ctx_t *hash_ctx;
if (context == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_CONTEXT, "ali_hash_reset: invalid context!\n");
}
hash_ctx = (hash_ctx_t *)context;
#if 0
if (!IS_VALID_CTX_MAGIC(hash_ctx->magic)) {
PRINT_RET(ALI_CRYPTO_INVALID_CONTEXT, "ali_hash_reset: bad magic!");
}
#endif
OSA_memset(hash_ctx, 0, sizeof(hash_ctx_t));
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_hash_copy_context(void *dst_ctx, void *src_ctx)
{
hash_ctx_t *hash_ctx_src, *hash_ctx_dst;
if ((src_ctx == NULL) || (dst_ctx == NULL)) {
MBED_DBG_E("ali_hash_copy_context: bad input args!\n");
return ALI_CRYPTO_INVALID_ARG;
}
hash_ctx_src = (hash_ctx_t *)src_ctx;
if (!IS_VALID_CTX_MAGIC(hash_ctx_src->magic)) {
MBED_DBG_E("ali_hash_copy_context: bad magic!\n");
return ALI_CRYPTO_INVALID_CONTEXT;
}
/* only can copy to one un-initialized context */
hash_ctx_dst = (hash_ctx_t *)dst_ctx;
if ((IS_VALID_CTX_MAGIC(hash_ctx_dst->magic)) &&
((hash_ctx_dst->status == CRYPTO_STATUS_INITIALIZED) ||
(hash_ctx_dst->status == CRYPTO_STATUS_PROCESSING) ||
(hash_ctx_dst->status == CRYPTO_STATUS_FINISHED))) {
MBED_DBG_E("ali_hash_copy_context: bad status(%d)\n",
(int)hash_ctx_dst->status);
return ALI_CRYPTO_ERR_STATE;
}
OSA_memcpy(hash_ctx_dst, hash_ctx_src, sizeof(hash_ctx_t));
return ALI_CRYPTO_SUCCESS;
}

View file

@ -0,0 +1,155 @@
/*
* Copyright (C) 2017 The YunOS Project. All rights reserved.
*/
#ifndef _MBED_CRYPTO_H_
#define _MBED_CRYPTO_H_
#include "ali_crypto.h"
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "aes.h"
#include "sha1.h"
#include "sha256.h"
#include "sha512.h"
#include "md.h"
#include "hash.h"
#include "md5.h"
#include "rsa.h"
#include "hmac.h"
#if CONFIG_DBG_CRYPT
#define MBED_DBG_E(_f, _a ...) \
printf("E %s %d: "_f, __FUNCTION__, __LINE__, ##_a)
#define MBED_DBG_I(_f, ...) \
printf("I %s %d: "_f, __FUNCTION__, __LINE__, ##_a)
#else
#define MBED_DBG_E(_f, _a...)
#define MBED_DBG_I(_f, _a...)
#endif
#define PRINT_RET(_ret, _f, ...) \
do { \
MBED_DBG_E(_f, ##__VA_ARGS__); \
return (ali_crypto_result)_ret; \
} while (0);
#define GO_RET(_ret, _f, ...) \
do { \
MBED_DBG_E(_f, ##__VA_ARGS__); \
result = (ali_crypto_result)_ret; \
goto _OUT; \
} while (0);
#define INIT_CTX_MAGIC(m) (m = 0x12345678)
#define IS_VALID_CTX_MAGIC(m) (0x12345678 == m)
#define CLEAN_CTX_MAGIC(m) (m = 0x0)
#ifdef MBEDTLS_IOT_PLAT_AOS
#include <aos/kernel.h>
#define OSA_malloc(_size) aos_malloc(_size)
#define OSA_free(_ptr) aos_free(_ptr)
#else
#define OSA_malloc(_size) malloc(_size)
#define OSA_free(_ptr) free(_ptr)
#endif
#define OSA_memcpy(_dst, _src, _size) memcpy(_dst, _src, _size)
#define OSA_memset(_src, _val, _size) memset(_src, _val, _size)
#define OSA_memcmp(_dst, _src, _size) memcmp(_dst, _src, _size)
#define OSA_strlen(_str) strlen(_str)
enum
{
PK_PUBLIC = 0,
PK_PRIVATE = 1
};
typedef struct _hash_ctx_t
{
uint32_t magic;
uint32_t status;
hash_type_t type;
union
{
uint8_t sym_ctx[1];
mbedtls_md5_context md5_ctx;
mbedtls_sha1_context sha1_ctx;
mbedtls_sha256_context sha256_ctx;
mbedtls_sha512_context sha512_ctx;
};
} hash_ctx_t;
typedef struct _hmac_ctx_t
{
uint32_t magic;
uint32_t status;
hash_type_t type;
union
{
uint8_t sym_ctx[1];
mbedtls_hash_context_t ctx;
};
} hmac_ctx_t;
typedef struct _cts_ctx_t
{
uint32_t is_ecb;
} cts_ctx_t;
typedef struct _xts_ctx_t
{
uint8_t tweak[16];
} xts_ctx_t;
typedef struct _aes_ctx_t
{
uint32_t magic;
uint32_t status;
aes_type_t type;
uint32_t is_enc;
uint8_t iv[AES_IV_SIZE];
size_t offset;
uint8_t stream_block[AES_BLOCK_SIZE];
union
{
uint8_t sym_ctx[1];
mbedtls_aes_context ctx;
};
} aes_ctx_t;
typedef struct _des_ctx_t
{
uint32_t magic;
uint32_t status;
des_type_t type;
uint32_t is_enc;
union
{
uint8_t sym_ctx[1];
};
} des_ctx_t;
typedef struct _ae_ctx_t
{
uint32_t magic;
uint32_t status;
authenc_type_t type;
uint32_t is_enc;
uint32_t tag_len;
} ae_ctx_t;
ali_crypto_result mbed_crypto_init(void);
void mbed_crypto_cleanup(void);
#endif /* _MBED_CRYPTO_H_ */

View file

@ -0,0 +1,309 @@
/**
* Copyright (C) 2017 The YunOS Project. All rights reserved.
*/
#include "mbed_crypto.h"
#include "ali_crypto.h"
ali_crypto_result ali_hmac_get_ctx_size(hash_type_t type, size_t *size)
{
if (size == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG, "get_ctx_size: bad input!\n");
}
switch(type) {
case SHA1:
case SHA224:
case SHA256:
case SHA384:
case SHA512:
case MD5:
break;
default:
PRINT_RET(ALI_CRYPTO_INVALID_TYPE,
"get_ctx_size: invalid hmac type(%d)\n", type);
}
*size = sizeof(hmac_ctx_t);
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_hmac_init(hash_type_t type,
const uint8_t *key, size_t keybytes, void *context)
{
int ret;
hmac_ctx_t *hmac_ctx;
const mbedtls_hash_info_t *md_info;
mbedtls_md_type_t md_type;
int zero_tmp_key;
if (context == NULL ||
((key == NULL) && (keybytes != 0))) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG, "ali_hmac_init: bad input args!\n");
}
hmac_ctx = (hmac_ctx_t *)context;
if ((IS_VALID_CTX_MAGIC(hmac_ctx->magic) &&
hmac_ctx->status != CRYPTO_STATUS_FINISHED) &&
hmac_ctx->status != CRYPTO_STATUS_CLEAN) {
PRINT_RET(ALI_CRYPTO_ERR_STATE,
"ali_hmac_init: bad status(%d)\n", (int)hmac_ctx->status);
}
mbedtls_hash_init(&hmac_ctx->ctx);
switch(type) {
case SHA1: {
md_type = MBEDTLS_MD_SHA1;
break;
}
case SHA224: {
md_type = MBEDTLS_MD_SHA224;
break;
}
case SHA256: {
md_type = MBEDTLS_MD_SHA256;
break;
}
case SHA384: {
md_type = MBEDTLS_MD_SHA384;
break;
}
case SHA512: {
md_type = MBEDTLS_MD_SHA512;
break;
}
case MD5: {
md_type = MBEDTLS_MD_MD5;
break;
}
default:
PRINT_RET(ALI_CRYPTO_INVALID_TYPE,
"ali_hmac_init: invalid hash type(%d)\n", type);
}
md_info = mbedtls_hash_info_from_type(md_type);
if(NULL == md_info) {
PRINT_RET(ALI_CRYPTO_INVALID_TYPE,
"ali_hmac_init: invalid hash type(%d)\n", md_type);
}
ret = mbedtls_hash_setup(&hmac_ctx->ctx, md_info, 1);
if(0 != ret) {
PRINT_RET(ALI_CRYPTO_INVALID_TYPE,
"ali_hmac_init: invalid hash type(%d)\n", md_type);
}
if (keybytes) {
ret = mbedtls_hmac_starts(&hmac_ctx->ctx, key, keybytes);
} else {
/* feed 4 bytes zero key */
zero_tmp_key = 0;
ret = mbedtls_hmac_starts(&hmac_ctx->ctx,
(const unsigned char *)&zero_tmp_key,
(size_t)(sizeof(zero_tmp_key)));
}
if (ALI_CRYPTO_SUCCESS != ret) {
mbedtls_hash_free(&hmac_ctx->ctx);
PRINT_RET(ALI_CRYPTO_ERROR, "ali_hmac_init: fail to init hmac!\n");
}
hmac_ctx->type = type;
hmac_ctx->status = CRYPTO_STATUS_INITIALIZED;
INIT_CTX_MAGIC(hmac_ctx->magic);
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_hmac_update(const uint8_t *src, size_t size, void *context)
{
int ret;
hmac_ctx_t *hmac_ctx;
if (context == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_CONTEXT, "ali_hmac_update: bad ctx!\n");
}
if (src == NULL && size != 0) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG, "ali_hmac_update: bad args!\n");
}
hmac_ctx = (hmac_ctx_t *)context;
if (!IS_VALID_CTX_MAGIC(hmac_ctx->magic)) {
PRINT_RET(ALI_CRYPTO_INVALID_CONTEXT, "ali_hmac_update: bad magic!\n");
}
if ((hmac_ctx->status != CRYPTO_STATUS_INITIALIZED) &&
(hmac_ctx->status != CRYPTO_STATUS_PROCESSING)) {
PRINT_RET(ALI_CRYPTO_ERR_STATE,
"ali_hmac_update: bad status(%d)\n", (int)hmac_ctx->status);
}
ret = mbedtls_hmac_update(&hmac_ctx->ctx,
(const unsigned char *)src, size);
if (ALI_CRYPTO_SUCCESS != ret) {
PRINT_RET(ALI_CRYPTO_ERROR, "ali_hmac_update: hmac_process fail!\n");
}
hmac_ctx->status = CRYPTO_STATUS_PROCESSING;
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_hmac_final(uint8_t *dgst, void *context)
{
int ret;
hmac_ctx_t *hmac_ctx;
if (context == NULL || dgst == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG, "ali_hmac_final: bad input args!\n");
}
hmac_ctx = (hmac_ctx_t *)context;
if (!IS_VALID_CTX_MAGIC(hmac_ctx->magic)) {
PRINT_RET(ALI_CRYPTO_INVALID_CONTEXT, "ali_hmac_final: bad magic!\n");
}
if ((hmac_ctx->status != CRYPTO_STATUS_INITIALIZED) &&
(hmac_ctx->status != CRYPTO_STATUS_PROCESSING)) {
PRINT_RET(ALI_CRYPTO_ERR_STATE,
"ali_hmac_final: bad status(%d)\n", (int)hmac_ctx->status);
}
ret = mbedtls_hmac_finish(&hmac_ctx->ctx, dgst);
if (ALI_CRYPTO_SUCCESS != ret) {
PRINT_RET(ALI_CRYPTO_ERROR, "ali_hmac_final: hmac_done fail!\n");
}
CLEAN_CTX_MAGIC(hmac_ctx->magic);
hmac_ctx->status = CRYPTO_STATUS_FINISHED;
mbedtls_hash_free(&hmac_ctx->ctx);
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_hmac_digest(hash_type_t type,
const uint8_t *key, size_t keybytes,
const uint8_t *src, size_t size, uint8_t *dgst)
{
int ret;
const mbedtls_hash_info_t *md_info;
mbedtls_md_type_t md_type;
if ((src == NULL && size != 0) ||
key == NULL || keybytes == 0|| dgst == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG, "ali_hmac_digest: bad input args!\n");
}
switch(type) {
case SHA1: {
md_type = MBEDTLS_MD_SHA1;
break;
}
case SHA224: {
md_type = MBEDTLS_MD_SHA224;
break;
}
case SHA256: {
md_type = MBEDTLS_MD_SHA256;
break;
}
case SHA384: {
md_type = MBEDTLS_MD_SHA384;
break;
}
case SHA512: {
md_type = MBEDTLS_MD_SHA512;
break;
}
case MD5: {
md_type = MBEDTLS_MD_MD5;
break;
}
default:
PRINT_RET(ALI_CRYPTO_INVALID_TYPE,
"ali_hmac_digest: invalid hash type(%d)\n", type);
}
md_info = mbedtls_hash_info_from_type(md_type);
if(NULL == md_info) {
PRINT_RET(ALI_CRYPTO_INVALID_TYPE,
"ali_hmac_init: invalid hash type(%d)\n", md_type);
}
ret = mbedtls_hash_hmac(md_info, key, keybytes, src, size, dgst);
if (ret != ALI_CRYPTO_SUCCESS) {
PRINT_RET(ALI_CRYPTO_ERROR, "ali_hmac_digest: hmac_memory fail!\n");
}
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_hmac_reset(void *context)
{
hmac_ctx_t *hmac_ctx;
int32_t ret;
if (context == NULL) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG, "ali_hmac_reset: bad input args!\n");
}
hmac_ctx = (hmac_ctx_t *)context;
if (!IS_VALID_CTX_MAGIC(hmac_ctx->magic)) {
PRINT_RET(ALI_CRYPTO_INVALID_CONTEXT, "ali_hmac_reset: bad magic!\n");
}
ret = mbedtls_hmac_reset(&hmac_ctx->ctx);
if (0 != ret) {
PRINT_RET(ALI_CRYPTO_ERROR,
"ali_hmac_reset: mbedtls_md_hmac_reset fial %d!\n", (int)ret);
}
OSA_memset(hmac_ctx, 0, sizeof(hmac_ctx_t));
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_hmac_copy_context(void *dst_ctx, void *src_ctx)
{
hmac_ctx_t *hmac_ctx_src, *hmac_ctx_dst;
if ((src_ctx == NULL) || (dst_ctx == NULL)) {
PRINT_RET(ALI_CRYPTO_INVALID_ARG,
"ali_hmac_copy_context: bad input args!\n");
}
hmac_ctx_src = (hmac_ctx_t *)src_ctx;
if (!IS_VALID_CTX_MAGIC(hmac_ctx_src->magic)) {
PRINT_RET(ALI_CRYPTO_INVALID_CONTEXT,
"ali_hmac_copy_context: bad magic!\n");
}
/* only can copy to one un-initialized context */
hmac_ctx_dst = (hmac_ctx_t *)dst_ctx;
if ((IS_VALID_CTX_MAGIC(hmac_ctx_dst->magic)) &&
((hmac_ctx_dst->status == CRYPTO_STATUS_INITIALIZED) ||
(hmac_ctx_dst->status == CRYPTO_STATUS_PROCESSING) ||
(hmac_ctx_dst->status == CRYPTO_STATUS_FINISHED))) {
PRINT_RET(ALI_CRYPTO_ERR_STATE,
"ali_hmac_copy_context: bad status(%d)\n", (int)hmac_ctx_dst->status);
}
OSA_memcpy(hmac_ctx_dst, hmac_ctx_src, sizeof(hmac_ctx_t));
return ALI_CRYPTO_SUCCESS;
}

View file

@ -0,0 +1,5 @@
/**
* Copyright (C) 2017 The YunOS Project. All rights reserved.
**/

View file

@ -0,0 +1,444 @@
/**
* Copyright (C) 2016 The YunOS Project. All rights reserved.
*/
#include "tee_osa.h"
#include "tomcrypt.h"
static int _g_prng_idx = 0;
static prng_state _g_prng_state;
static uint8_t RSA_1024_N[128] = {
0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58,
0x9a, 0x51, 0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1,
0x56, 0xf2, 0xec, 0x0e, 0x36, 0xad, 0x52, 0xa4,
0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a, 0xd9, 0x91,
0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62,
0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3,
0x94, 0xdf, 0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb,
0xb3, 0x07, 0xce, 0xab, 0xfc, 0xe0, 0xb1, 0xdf,
0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d, 0x5b, 0x2b,
0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70,
0xe2, 0x59, 0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1,
0x05, 0xac, 0xc2, 0xd3, 0xf0, 0xcb, 0x35, 0xf2,
0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f, 0x64, 0xc4,
0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37
};
static uint8_t RSA_1024_E[3] = {0x01, 0x00, 0x01};
static uint8_t RSA_1024_D[128] = {
0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f,
0x54, 0x51, 0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47,
0x71, 0xa1, 0x01, 0xaf, 0x88, 0x43, 0x40, 0xae,
0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe, 0x92, 0xe8,
0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f,
0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8,
0xc6, 0xa3, 0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1,
0x12, 0x31, 0x88, 0x44, 0x29, 0xfc, 0x4d, 0x9a,
0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10, 0xce, 0x70,
0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83,
0x10, 0x9c, 0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c,
0x31, 0xb4, 0xbd, 0x2f, 0x53, 0xc3, 0xee, 0x37,
0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e, 0x50, 0x3b,
0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25
};
static void _print_data(const char *name, uint8_t *data, size_t size)
{
size_t i;
if (data == NULL || size == 0) {
printf("print_data: no data\n");
return;
}
printf("%s size: %d\n", name, size);
for (i = 0; i < size - size % 8; i += 8) {
printf("%s data: %02x%02x %02x%02x %02x%02x %02x%02x\n",
name,
data[i+0], data[i+1], data[i+2], data[i+3],
data[i+4], data[i+5], data[i+6], data[i+7]);
}
while(i < size) {
printf("%s data: %02x\n", name, data[i]);
i++;
}
return;
}
static void _print_rsa_key(rsa_key *key)
{
uint32_t len;
uint8_t tmp[256];
printf("RSA %s key:\n", (key->type == PK_PUBLIC)? "public" : "private");
if (key->type == PK_PUBLIC) {
len = mp_unsigned_bin_size(key->N);
mp_to_unsigned_bin(key->N, tmp);
_print_data("RSA N", tmp, len);
len = mp_unsigned_bin_size(key->e);
mp_to_unsigned_bin(key->e, tmp);
_print_data("RSA e", tmp, len);
} else {
len = mp_unsigned_bin_size(key->N);
mp_to_unsigned_bin(key->N, tmp);
_print_data("RSA N", tmp, len);
len = mp_unsigned_bin_size(key->e);
mp_to_unsigned_bin(key->e, tmp);
_print_data("RSA e", tmp, len);
len = mp_unsigned_bin_size(key->d);
mp_to_unsigned_bin(key->d, tmp);
_print_data("RSA d", tmp, len);
}
return;
}
static int _rsa_test_gen_key(rsa_key *key)
{
int ret;
ret = rsa_make_key(&_g_prng_state, _g_prng_idx, 1024/8, 65537, key);
if (ret != CRYPT_OK) {
printf("rsa make key fail(%d)\n", ret);
return -1;
}
return 0;
}
static int _rsa_test_init_key(rsa_key *key)
{
int ret;
int type;
type = key->type;
memset(key, 0, sizeof(rsa_key));
key->type = type;
ret = mp_init_multi(&key->N, &key->e, &key->d, NULL);
if (ret < 0) {
printf("init_key: mp init multi fail(%d)\n", ret);
return -1;
}
if (key->type == PK_PUBLIC) {
mp_read_unsigned_bin(key->N, RSA_1024_N, 1024/8);
mp_read_unsigned_bin(key->e, RSA_1024_E, 3);
} else {
mp_read_unsigned_bin(key->N, RSA_1024_N, 1024/8);
mp_read_unsigned_bin(key->e, RSA_1024_E, 3);
mp_read_unsigned_bin(key->d, RSA_1024_D, 1024/8);
}
return 0;
}
static int _rsa_test_encrypt_decrypt_nopad(void)
{
int ret = 0;
rsa_key key;
uint8_t src_data[128];
uint8_t plaintext[128];
uint8_t ciphertext[128];
ulong_t src_size = 128;
ulong_t dst_size = 128;
ret = _rsa_test_gen_key(&key);
if (ret < 0) {
printf("rsa gen key fail\n");
return -1;
}
/* public encrypt */
memset(src_data, 0xa, src_size);
ret = rsa_exptmod(src_data, src_size,
ciphertext, &dst_size, PK_PUBLIC, &key);
if (ret != CRYPT_OK) {
printf("public encrypt fail(%d)\n", ret);
goto _out;
}
/* private decrypt */
dst_size = 128;
ret = rsa_exptmod(ciphertext, src_size,
plaintext, &dst_size, PK_PRIVATE, &key);
if (ret != CRYPT_OK) {
printf("private decrypt fail(%d)\n", ret);
goto _out;
}
if (memcmp(src_data, plaintext, src_size)) {
printf("RSA encrypt and decrypt with no-padding fail!\n");
_print_data("plaintext", plaintext, dst_size);
_print_data("ciphertext", ciphertext, dst_size);
} else {
printf("RSA encrypt and decrypt with no-padding success!\n");
}
_out:
rsa_free(&key);
return ret;
}
static int _rsa_test_encrypt_decrypt_v1_5(void)
{
int ret, stat;
rsa_key key;
uint8_t src_data[128];
uint8_t plaintext[128];
uint8_t ciphertext[128];
ulong_t src_size = 117;
ulong_t dst_size = 128;
ret = _rsa_test_gen_key(&key);
if (ret < 0) {
printf("rsa gen key fail\n");
return -1;
}
/* public encrypt */
memset(src_data, 0xa, src_size);
ret = rsa_encrypt_key_ex(src_data, src_size, ciphertext, &dst_size,
NULL, 0, &_g_prng_state, _g_prng_idx, 0, LTC_PKCS_1_V1_5, &key);
if (ret != CRYPT_OK) {
printf("public encrypt with pkcs1_v1_5 fail(%d)\n", ret);
goto _out;
}
/* private decrypt */
dst_size = 128;
ret = rsa_decrypt_key_ex(ciphertext, 128, plaintext, &dst_size,
NULL, 0, 0, LTC_PKCS_1_V1_5, &stat, &key);
if (ret != CRYPT_OK || stat != 1) {
printf("private decrypt with pkcs1_v1_5 fail(%d)\n", ret);
goto _out;
}
if (memcmp(src_data, plaintext, src_size)) {
printf("RSA encrypt and decrypt with pkcs1_v1_5 fail!\n");
_print_data("plaintext", plaintext, src_size);
_print_data("ciphertext", ciphertext, dst_size);
} else {
printf("RSA encrypt and decrypt with pkcs1_v_5 success!\n");
}
_out:
rsa_free(&key);
return ret;
}
static int _rsa_test_encrypt_decrypt_oaep(void)
{
int ret, stat;
rsa_key key;
int hash_idx;
uint8_t src_data[128];
uint8_t plaintext[128];
uint8_t ciphertext[128];
ulong_t src_size = 86;
ulong_t dst_size = 128;
uint8_t lparam[] = {0x01, 0x02, 0x03, 0x04};
key.type = PK_PRIVATE;
ret = _rsa_test_init_key(&key);
if (ret < 0) {
printf("rsa init key fail\n");
return -1;
}
hash_idx = find_hash("sha1");
if (hash_idx < 0) {
printf("not find sha1\n");
return -1;
}
/* public encrypt without lparam */
memset(src_data, 0xa, src_size);
ret = rsa_encrypt_key_ex(src_data, src_size, ciphertext, &dst_size,
NULL, 0, &_g_prng_state, _g_prng_idx, hash_idx, LTC_PKCS_1_OAEP, &key);
if (ret != CRYPT_OK) {
printf("public encrypt with oaep(without lparam) fail(%d)\n", ret);
goto _out;
}
/* private decrypt without lparam*/
ret = rsa_decrypt_key_ex(ciphertext, 128, plaintext, &dst_size,
NULL, 0, hash_idx, LTC_PKCS_1_OAEP, &stat, &key);
if (ret != CRYPT_OK || stat != 1) {
printf("private decrypt with oaep(without lparam) fail(%d)\n", ret);
goto _out;
}
if (memcmp(src_data, plaintext, src_size)) {
printf("RSA encrypt and decrypt with pkcs1_oaep(without lparam) fail!\n");
_print_data("plaintext", plaintext, src_size);
_print_data("ciphertext", ciphertext, dst_size);
} else {
printf("RSA encrypt and decrypt with pkcs1_oaep(without lparam) success!\n");
}
/* public encrypt with lparam */
dst_size = 128;
ret = rsa_encrypt_key_ex(src_data, src_size, ciphertext, &dst_size,
lparam, sizeof(lparam), &_g_prng_state, _g_prng_idx, hash_idx, LTC_PKCS_1_OAEP, &key);
if (ret != CRYPT_OK) {
printf("public encrypt with oaep(with lparam) fail(%d)\n", ret);
goto _out;
}
/* private decrypt with lparam*/
ret = rsa_decrypt_key_ex(ciphertext, 128, plaintext, &dst_size,
lparam, sizeof(lparam), hash_idx, LTC_PKCS_1_OAEP, &stat, &key);
if (ret != CRYPT_OK || stat != 1) {
printf("private decrypt with oaep(with lparam) fail(%d)\n", ret);
goto _out;
}
if (memcmp(src_data, plaintext, src_size)) {
printf("RSA encrypt and decrypt with pkcs1_oaep(with lparam) fail!\n");
_print_data("plaintext", plaintext, src_size);
_print_data("ciphertext", ciphertext, dst_size);
} else {
printf("RSA encrypt and decrypt with pkcs1_oaep(with lparam) success!\n");
}
_out:
rsa_free(&key);
return ret;
}
static int _rsa_test_sign_verify(void)
{
int ret;
int stat;
rsa_key key;
int hash_idx;
ulong_t src_size;
ulong_t sig_size = 128;
uint8_t src_data[64];
uint8_t signature[128];
ret = _rsa_test_gen_key(&key);
if (ret < 0) {
printf("rsa gen key fail\n");
return -1;
}
hash_idx = find_hash("sha1");
if (hash_idx < 0) {
printf("not find hash\n");
return -1;
}
src_size = 20;
/* private sign with v1_5 padding */
memset(src_data, 0xa, 64);
ret = rsa_sign_hash_ex(src_data, src_size, signature, &sig_size,
LTC_PKCS_1_V1_5, &_g_prng_state, _g_prng_idx,
hash_idx, 0, &key);
if (ret != CRYPT_OK) {
printf("rsa private sign(v1_5) fail(%d)\n", ret);
goto _out;
}
/* public verify with v1_5 padding */
key.type = PK_PUBLIC;
ret = rsa_verify_hash_ex(signature, sig_size, src_data, src_size,
LTC_PKCS_1_V1_5, hash_idx, 0, &stat, &key);
if (ret != CRYPT_OK || stat != 1) {
printf("RSA public verify(v1_5) fail(ret; %d stat: %d)\n", ret , stat);
_print_data("v1_5_sig", signature, sig_size);
ret = -1;
goto _out;
} else {
printf("rsa public verify(v1_5) success!\n");
}
/* private sign with pss padding */
key.type = PK_PRIVATE;
ret = rsa_sign_hash_ex(src_data, src_size, signature, &sig_size,
LTC_PKCS_1_PSS, &_g_prng_state, _g_prng_idx,
hash_idx, 8, &key);
if (ret != CRYPT_OK) {
printf("RSA private sign(pss) fail(%d)\n", ret);
goto _out;
}
/* public verify with pss padding */
key.type = PK_PUBLIC;
ret = rsa_verify_hash_ex(signature, sig_size, src_data, src_size,
LTC_PKCS_1_PSS, hash_idx, 8, &stat, &key);
if (ret != CRYPT_OK || stat != 1) {
printf("RSA public verify(pss) fail(ret; %d stat: %d)\n", ret , stat);
_print_data("pss_sig", signature, sig_size);
ret = -1;
goto _out;
} else {
printf("RSA public verify(pss) success!\n");
}
_out:
rsa_free(&key);
return ret;
}
static void _mbed_crypto_rsa_test(uint32_t level)
{
int ret;
rsa_key key;
#if 0
ret = _rsa_test_gen_key(&key);
if (ret < 0) {
printf("rsa gen key fail\n");
return;
}
rsa_free(&key);
#endif
key.type = PK_PRIVATE;
ret = _rsa_test_init_key(&key);
if (ret < 0) {
printf("rsa gen key fail\n");
return;
}
rsa_free(&key);
ret = _rsa_test_encrypt_decrypt_nopad();
if (ret < 0) {
printf("rsa encrypt decrypt with nopad test fail\n");
return;
}
ret = _rsa_test_encrypt_decrypt_v1_5();
if (ret < 0) {
printf("rsa encrypt decrypt with pkcs1_v_5 test fail\n");
return;
}
ret = _rsa_test_encrypt_decrypt_oaep();
if (ret < 0) {
printf("rsa encrypt decrypt with pkcs1_oaep test fail\n");
return;
}
ret = _rsa_test_sign_verify();
if (ret < 0) {
printf("rsa sign verify test fail\n");
return;
}
return;
}

View file

@ -0,0 +1,54 @@
/**
* Copyright (C) 2017 The YunOS Project. All rights reserved.
**/
#include "ali_crypto.h"
#include "mbed_crypto.h"
//static uint32_t next = 1;
static uint32_t randseed = 12345;
uint32_t ali_crypt_rand_word(void)
{
return (randseed = randseed * 1664525 + 1013904223);
}
ali_crypto_result ali_rand_gen(uint8_t *buf, size_t len)
{
uint32_t i;
uint32_t tmp;
if (buf == NULL || len == 0) {
MBED_DBG_E("ali_rand_gen: invalid input args!\n");
return ALI_CRYPTO_INVALID_ARG;
}
tmp = ali_crypt_rand_word();
for (i = 0; i < len; i++) {
if ((i & 3) == 0) {
tmp = ali_crypt_rand_word();
}
buf[i] = ((tmp >> ((i & 3) << 3)) & 0xff);
}
return ALI_CRYPTO_SUCCESS;
}
ali_crypto_result ali_seed(uint8_t *seed, size_t seed_len)
{
uint32_t i, tmp = 0;
for (i = 0; i < (seed_len - seed_len % 4); i += 4) {
tmp ^= seed[i];
tmp ^= seed[i + 1] << 8;
tmp ^= seed[i + 2] << 16;
tmp ^= seed[i + 3] << 24;
}
while (i < seed_len) {
tmp ^= seed[i++];
}
randseed = tmp;
return ALI_CRYPTO_SUCCESS;
}

View file

@ -0,0 +1,14 @@
/*
* Copyright (C) 2016 The YunOS Project. All rights reserved.
*/
#ifndef _ALI_CRYPTO_RAND_H_
#define _ALI_CRYPTO_RAND_H_
#include "ali_crypto.h"
extern void ali_crypt_rand_reseed(uint32_t seed);
extern uint32_t ali_crypt_rand_word(void);
extern uint32_t ali_crypt_rand_bytes(uint8_t *buf, uint32_t len);
#endif /* _ALI_CRYPTO_RAND_H_ */

View file

@ -0,0 +1,62 @@
/**
* Copyright (C) 2016 The YunOS Project. All rights reserved.
*/
#include "ali_crypto.h"
#include "ali_crypto_test.h"
void ali_crypto_test_entry(void)
{
int ret;
/* for gcov coverage */
ali_crypto_print_data("alicrypto TEST", (uint8_t *)"\n", 1);
ret = ali_crypto_init();
if (ret < 0) {
goto _OUT;
}
CRYPT_INF("Test hash:\n");
ret = ali_crypto_hash_test();
if (ret < 0) {
goto _OUT;
}
CRYPT_INF("Test hmac:\n");
ret = ali_crypto_hmac_test();
if (ret < 0) {
goto _OUT;
}
CRYPT_INF("Test rand:\n");
ret = ali_crypto_rand_test();
if (ret < 0) {
goto _OUT;
}
CRYPT_INF("Test aes:\n");
ret = ali_crypto_aes_test();
if (ret < 0) {
goto _OUT;
}
CRYPT_INF("Test rsa:\n");
ret = ali_crypto_rsa_test();
if (ret < 0) {
goto _OUT;
}
_OUT:
ali_crypto_cleanup();
return;
}
#if 0
int main(void)
{
ali_crypto_test_entry();
return 0;
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,29 @@
/**
* Copyright (C) 2016 The YunOS Project. All rights reserved.
*/
#include "ali_crypto_test.h"
void ali_crypto_print_data(const char *name, uint8_t *data, size_t size)
{
size_t i;
if (data == NULL || size == 0) {
CRYPT_ERR("print_data: no data\n");
return;
}
CRYPT_INF("%s size: %d\n", name, (int)size);
for (i = 0; i < size - size % 8; i += 8) {
CRYPT_INF("%s data: %02x%02x %02x%02x %02x%02x %02x%02x\n",
name,
data[i+0], data[i+1], data[i+2], data[i+3],
data[i+4], data[i+5], data[i+6], data[i+7]);
}
while(i < size) {
CRYPT_INF("%s data: %02x\n", name, data[i]);
i++;
}
return;
}

View file

@ -0,0 +1,245 @@
/**
* Copyright (C) 2017 The YunOS Project. All rights reserved.
*/
#include "ali_crypto.h"
#include "ali_crypto_test.h"
#define TEST_DATA_SIZE (141)
static uint8_t _g_test_data[TEST_DATA_SIZE] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0c, 0x0d,
0x0e, 0x0f, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x13
};
/* openssl calculated result */
static uint8_t hash_md5[MD5_HASH_SIZE] = { 0x95, 0x79, 0xa2, 0x46, 0x8e, 0xbc,
0x5b, 0xd6, 0x45, 0x57, 0xbb, 0x4f,
0xaf, 0xae, 0x5a, 0x05 };
static int8_t hash_sha1[SHA1_HASH_SIZE] = { 0x54, 0x1d, 0x6f, 0x6e, 0x46,
0x7e, 0xfe, 0x1d, 0xa8, 0x66,
0x06, 0x34, 0xb0, 0x21, 0x3d,
0x65, 0xb8, 0xa4, 0x02, 0xca };
static uint8_t hash_sha224[SHA224_HASH_SIZE] = {
0x36, 0x94, 0x36, 0xf9, 0xd4, 0xe9, 0xbe, 0x59, 0xbb, 0x59,
0x5c, 0x73, 0x4a, 0xf0, 0xe8, 0x52, 0x48, 0x09, 0x84, 0x42,
0xec, 0x80, 0xdb, 0x86, 0x5a, 0x51, 0x44, 0x3a
};
static uint8_t hash_sha256[SHA256_HASH_SIZE] = {
0x3b, 0x7f, 0x52, 0xae, 0x5b, 0xe8, 0x09, 0x19, 0x02, 0x1a, 0x83,
0x8d, 0xcc, 0xc6, 0x01, 0xc3, 0x76, 0x41, 0x22, 0x64, 0x4b, 0x1c,
0x35, 0xa2, 0x9d, 0xd3, 0xc5, 0x76, 0x36, 0xd7, 0xda, 0x5f
};
static uint8_t hash_sha384[SHA384_HASH_SIZE] = {
0x21, 0xc7, 0x05, 0xb3, 0x37, 0x66, 0xf3, 0xb5, 0x0d, 0x51, 0xf5, 0x0f,
0x91, 0xfc, 0xa1, 0xcf, 0x78, 0x35, 0x82, 0x77, 0xfd, 0x2c, 0x31, 0xbb,
0x8a, 0x26, 0x6f, 0x2a, 0x82, 0x52, 0x1a, 0x70, 0xfd, 0xfc, 0xa2, 0xb7,
0xee, 0x7f, 0xb5, 0xfd, 0x9e, 0x20, 0x36, 0x91, 0xc6, 0xd6, 0x54, 0xa0
};
static uint8_t hash_sha512[SHA512_HASH_SIZE] = {
0x9e, 0xca, 0x2a, 0x96, 0x01, 0x48, 0x0f, 0xa2, 0x6b, 0x99, 0x27,
0x1a, 0x7f, 0x72, 0xe3, 0xa4, 0xee, 0x2f, 0x08, 0x92, 0x2e, 0xdb,
0xf7, 0x19, 0xd8, 0xcd, 0xcb, 0xfc, 0x8b, 0x56, 0x8c, 0x04, 0xfb,
0xb3, 0x69, 0xdf, 0x26, 0xfb, 0x0b, 0x9f, 0xbe, 0x1d, 0x42, 0xbd,
0x39, 0x87, 0x52, 0x16, 0x42, 0xac, 0x62, 0x57, 0x94, 0x59, 0xa4,
0xce, 0x8d, 0x69, 0x78, 0xb7, 0xf8, 0x95, 0xb8, 0x78
};
int ali_crypto_hash_test(void)
{
ali_crypto_result result;
hash_type_t type;
void * hash_ctx = NULL;
size_t hash_ctx_size;
uint8_t hash[MAX_HASH_SIZE];
uint8_t hash_all[MAX_HASH_SIZE];
/* for gcov coverage */
result = ali_hash_get_ctx_size(HASH_NONE, &hash_ctx_size);
if (result == ALI_CRYPTO_SUCCESS) {
return -1;
}
/* for gcov coverage */
result = ali_hash_get_ctx_size(HASH_NONE, NULL);
if (result == ALI_CRYPTO_SUCCESS) {
return -1;
}
/* for gcov coverage */
result = ali_hash_init(HASH_NONE, NULL);
if (result == ALI_CRYPTO_SUCCESS) {
return -1;
}
/* for gcov coverage */
result = ali_hash_init(HASH_NONE, hash_ctx);
if (result == ALI_CRYPTO_SUCCESS) {
return -1;
}
/* for gcov coverage */
result = ali_hash_update(_g_test_data, 13, NULL);
if (result == ALI_CRYPTO_SUCCESS) {
return -1;
}
/* for gcov coverage */
result = ali_hash_update(NULL, 13, (void *)-1);
if (result == ALI_CRYPTO_SUCCESS) {
return -1;
}
/* for gcov coverage */
result = ali_hash_final(hash, NULL);
if (result == ALI_CRYPTO_SUCCESS) {
return -1;
}
/* for gcov coverage */
result = ali_hash_final(hash, NULL);
if (result == ALI_CRYPTO_SUCCESS) {
return -1;
}
/* for gcov coverage */
result = ali_hash_reset(NULL);
if (result == ALI_CRYPTO_SUCCESS) {
return -1;
}
/* for gcov coverage */
result = ali_hash_copy_context(NULL, NULL);
if (result == ALI_CRYPTO_SUCCESS) {
return -1;
}
for (type = SHA1; type <= MD5; type++) {
if (type == SHA512 || type == SHA384) {
CRYPT_INF("hash not support hash 384 512\n");
continue;
}
result = ali_hash_get_ctx_size(type, &hash_ctx_size);
if (result != ALI_CRYPTO_SUCCESS) {
GO_RET(result, "get ctx size fail(%08x)\n", result);
}
hash_ctx = CRYPT_MALLOC(hash_ctx_size);
if (hash_ctx == NULL) {
GO_RET(result, "malloc(%d) fail\n", (int)hash_ctx_size);
}
CRYPT_MEMSET(hash_ctx, 0, hash_ctx_size);
result = ali_hash_init(type, hash_ctx);
if (result != ALI_CRYPTO_SUCCESS) {
GO_RET(result, "init fail(%08x)", result);
}
result = ali_hash_update(_g_test_data, 13, hash_ctx);
if (result != ALI_CRYPTO_SUCCESS) {
GO_RET(result, "update 1th fail(%08x)", result);
}
result = ali_hash_update(_g_test_data + 13, 63, hash_ctx);
if (result != ALI_CRYPTO_SUCCESS) {
GO_RET(result, "update 2th fail(%08x)", result);
}
result = ali_hash_update(_g_test_data + 13 + 63, 65, hash_ctx);
if (result != ALI_CRYPTO_SUCCESS) {
GO_RET(result, "update 3th fail(%08x)", result);
}
result = ali_hash_final(hash, hash_ctx);
if (result != ALI_CRYPTO_SUCCESS) {
GO_RET(result, "final fail(%08x)", result);
}
result = ali_hash_digest(type, _g_test_data, TEST_DATA_SIZE, hash_all);
if (result != ALI_CRYPTO_SUCCESS) {
GO_RET(result, "digest fail(%08x)", result);
}
/* for gcov coverage */
result = ali_hash_copy_context(hash_ctx, hash_ctx);
if (result == ALI_CRYPTO_SUCCESS) {
result = ALI_CRYPTO_ERROR;
goto _OUT;
}
result = ali_hash_reset(hash_ctx);
if (result != ALI_CRYPTO_SUCCESS) {
result = ALI_CRYPTO_ERROR;
goto _OUT;
}
CRYPT_FREE(hash_ctx);
hash_ctx = NULL;
if (type == SHA1) {
if (CRYPT_MEMCMP(hash, hash_sha1, SHA1_HASH_SIZE) ||
CRYPT_MEMCMP(hash_all, hash_sha1, SHA1_HASH_SIZE)) {
ali_crypto_print_data("sha1", hash, SHA1_HASH_SIZE);
GO_RET(-1, "SHA1 test fail!");
} else {
CRYPT_INF("SHA1 test success!\n");
}
} else if (type == SHA224) {
if (CRYPT_MEMCMP(hash, hash_sha224, SHA224_HASH_SIZE) ||
CRYPT_MEMCMP(hash_all, hash_sha224, SHA224_HASH_SIZE)) {
ali_crypto_print_data("sha224", hash, SHA224_HASH_SIZE);
GO_RET(-1, "SHA224 test fail!\n");
} else {
CRYPT_INF("SHA224 test success!\n");
}
} else if (type == SHA256) {
if (CRYPT_MEMCMP(hash, hash_sha256, SHA256_HASH_SIZE) ||
CRYPT_MEMCMP(hash_all, hash_sha256, SHA256_HASH_SIZE)) {
ali_crypto_print_data("sha256", hash, SHA256_HASH_SIZE);
GO_RET(-1, "SHA256 test fail!\n");
} else {
CRYPT_INF("SHA256 test success!\n");
}
/* } else if (type == SHA384) {
if(CRYPT_MEMCMP(hash, hash_sha384, SHA384_HASH_SIZE) ||
CRYPT_MEMCMP(hash_all, hash_sha384,
SHA384_HASH_SIZE)) { ali_crypto_print_data("sha384", hash,
SHA384_HASH_SIZE); GO_RET(-1, "SHA384 test fail!\n"); } else {
CRYPT_INF("SHA384 test success!\n");
}
} else if (type == SHA512) {
if(CRYPT_MEMCMP(hash, hash_sha512, SHA512_HASH_SIZE) ||
CRYPT_MEMCMP(hash_all, hash_sha512,
SHA512_HASH_SIZE)) { ali_crypto_print_data("sha512", hash,
SHA512_HASH_SIZE); ali_crypto_print_data("sha512", hash_all,
SHA512_HASH_SIZE); GO_RET(-1, "SHA512 test fail!\n"); } else {
CRYPT_INF("SHA512 test success!\n");
}
*/
} else if (type == MD5) {
if (CRYPT_MEMCMP(hash, hash_md5, MD5_HASH_SIZE) ||
CRYPT_MEMCMP(hash_all, hash_md5, MD5_HASH_SIZE)) {
ali_crypto_print_data("md5", hash, MD5_HASH_SIZE);
GO_RET(-1, "md5 test fail!\n");
} else {
CRYPT_INF("md5 test success!\n");
}
}
}
return 0;
_OUT:
if (hash_ctx) {
CRYPT_FREE(hash_ctx);
}
return -1;
}

View file

@ -0,0 +1,228 @@
/**
* Copyright (C) 2016 The YunOS Project. All rights reserved.
*/
#include "ali_crypto.h"
#include "ali_crypto_test.h"
#define TEST_KEY_SIZE (16)
#define TEST_DATA_SIZE (141)
static uint8_t test_key[TEST_KEY_SIZE] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
0x07, 0x08, 0x08, 0x07, 0x06, 0x05,
0x04, 0x03, 0x02, 0x01 };
static uint8_t _g_test_data[TEST_DATA_SIZE] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0c, 0x0d,
0x0e, 0x0f, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x13
};
/* openssl calculated result */
static uint8_t hmac_md5[MD5_HASH_SIZE] = { 0x20, 0xc5, 0xc6, 0xa7, 0x17, 0x6f,
0x27, 0xfe, 0x7a, 0x1d, 0x7e, 0x85,
0x5b, 0x5c, 0xa8, 0xc4 };
static uint8_t hmac_sha1[SHA1_HASH_SIZE] = { 0xe5, 0xdf, 0x48, 0xfe, 0x08,
0x91, 0x37, 0xa2, 0x55, 0x95,
0xbc, 0xf3, 0x76, 0x06, 0x92,
0x1e, 0x54, 0x98, 0xe0, 0x4b };
static uint8_t hmac_sha224[SHA224_HASH_SIZE] = {
0x1c, 0x47, 0x04, 0x45, 0xcd, 0xee, 0x00, 0x9a, 0x46, 0x66,
0x2e, 0x1e, 0xb7, 0x04, 0xc9, 0x8f, 0xd5, 0xbb, 0x90, 0x38,
0xbb, 0x93, 0x9a, 0x08, 0x47, 0xe7, 0x17, 0xca
};
static uint8_t hmac_sha256[SHA256_HASH_SIZE] = {
0xd5, 0xce, 0x2b, 0x95, 0xa3, 0xea, 0x70, 0x69, 0x6a, 0x29, 0xbf,
0xe7, 0x9b, 0xa2, 0xc9, 0x18, 0x27, 0x4d, 0x3f, 0xd7, 0xae, 0xe7,
0x81, 0x88, 0x2a, 0xe7, 0x19, 0x68, 0x47, 0x07, 0xa3, 0xb3
};
static uint8_t hmac_sha384[SHA384_HASH_SIZE] = {
0x26, 0x10, 0x72, 0x0d, 0xf1, 0x70, 0x03, 0x40, 0x65, 0x4c, 0x94, 0xf5,
0x45, 0xbc, 0xbc, 0xcc, 0xd4, 0x17, 0xf5, 0x70, 0x81, 0xda, 0x91, 0x99,
0xe0, 0xca, 0x7a, 0x8c, 0x9c, 0x15, 0x5b, 0x22, 0xe8, 0xaa, 0x1c, 0xcf,
0xef, 0xe4, 0x6e, 0xf2, 0xfb, 0xdb, 0x6a, 0xf2, 0x22, 0xae, 0x70, 0x78
};
static uint8_t hmac_sha512[SHA512_HASH_SIZE] = {
0x66, 0x43, 0xba, 0xfc, 0x6f, 0x9e, 0xa3, 0xf8, 0xbf, 0x3d, 0x46,
0x46, 0x26, 0xfb, 0x8f, 0xa4, 0x04, 0x4c, 0x8a, 0x07, 0xfa, 0xac,
0x1d, 0x16, 0x33, 0xe6, 0xbd, 0x65, 0x01, 0xe2, 0x44, 0x83, 0x45,
0x78, 0x25, 0xbc, 0x42, 0x4b, 0x25, 0x85, 0xe0, 0x2a, 0xb4, 0xff,
0x6b, 0x92, 0x0c, 0x50, 0xdb, 0x0c, 0x00, 0x6e, 0x4d, 0xd5, 0x5c,
0xcc, 0x4e, 0x9f, 0xba, 0x3f, 0xfd, 0x81, 0x3f, 0x0b
};
int ali_crypto_hmac_test(void)
{
ali_crypto_result result;
hash_type_t type;
void * hmac_ctx = NULL;
uint32_t hmac_ctx_size;
uint8_t md[MAX_HASH_SIZE];
/* for gcov coverage */
result = ali_hmac_get_ctx_size(MD5, NULL);
if (result == ALI_CRYPTO_SUCCESS) {
return -1;
}
result = ali_hmac_get_ctx_size(HASH_NONE, (size_t *)(&hmac_ctx_size));
if (result == ALI_CRYPTO_SUCCESS) {
return -1;
}
result = ali_hmac_init(MD5, test_key, TEST_KEY_SIZE, NULL);
if (result == ALI_CRYPTO_SUCCESS) {
return -1;
}
result = ali_hmac_init(HASH_NONE, test_key, TEST_KEY_SIZE, NULL);
if (result == ALI_CRYPTO_SUCCESS) {
return -1;
}
result = ali_hmac_update(_g_test_data, 13, NULL);
if (result == ALI_CRYPTO_SUCCESS) {
return -1;
}
result = ali_hmac_final(md, NULL);
if (result == ALI_CRYPTO_SUCCESS) {
return -1;
}
result = ali_hmac_digest(MD5, NULL, TEST_KEY_SIZE, _g_test_data,
TEST_DATA_SIZE, md);
if (result == ALI_CRYPTO_SUCCESS) {
return -1;
}
result = ali_hmac_reset(NULL);
if (result == ALI_CRYPTO_SUCCESS) {
return -1;
}
result = ali_hmac_copy_context(NULL, NULL);
if (result == ALI_CRYPTO_SUCCESS) {
return -1;
}
for (type = SHA1; type <= MD5; type++) {
if (type == SHA512 || type == SHA384) {
CRYPT_INF("hmac not support hash 384 512\n");
continue;
}
result = ali_hmac_get_ctx_size(type, (size_t *)(&hmac_ctx_size));
if (result != ALI_CRYPTO_SUCCESS) {
GO_RET(result, "get ctx size fail(%08x)\n", result);
}
hmac_ctx = CRYPT_MALLOC(hmac_ctx_size);
if (hmac_ctx == NULL) {
GO_RET(ALI_CRYPTO_OUTOFMEM, "kmalloc(%08x) fail\n",
(int)hmac_ctx_size);
}
CRYPT_MEMSET(hmac_ctx, 0, hmac_ctx_size);
{
result = ali_hmac_init(type, test_key, TEST_KEY_SIZE, hmac_ctx);
if (result != ALI_CRYPTO_SUCCESS) {
GO_RET(result, "init fail(%08x)", result);
}
/* for gcov coverage */
result = ali_hmac_update(NULL, 13, hmac_ctx);
if (result == ALI_CRYPTO_SUCCESS) {
goto _OUT;
}
result = ali_hmac_update(_g_test_data, 13, hmac_ctx);
if (result != ALI_CRYPTO_SUCCESS) {
GO_RET(result, "update 1th fail(%08x)", result);
}
result = ali_hmac_update(_g_test_data + 13, 63, hmac_ctx);
if (result != ALI_CRYPTO_SUCCESS) {
GO_RET(result, "update 2th fail(%08x)", result);
}
result = ali_hmac_update(_g_test_data + 13 + 63, 65, hmac_ctx);
if (result != ALI_CRYPTO_SUCCESS) {
GO_RET(result, "update 3th fail(%08x)", result);
}
result = ali_hmac_final(md, hmac_ctx);
if (result != ALI_CRYPTO_SUCCESS) {
GO_RET(result, "final fail(%08x)", result);
}
/* for gcov coverage */
result = ali_hmac_digest(HASH_NONE, test_key, TEST_KEY_SIZE,
_g_test_data, TEST_DATA_SIZE, md);
if (result == ALI_CRYPTO_SUCCESS) {
goto _OUT;
}
result = ali_hmac_digest(type, test_key, TEST_KEY_SIZE,
_g_test_data, TEST_DATA_SIZE, md);
if (result != ALI_CRYPTO_SUCCESS) {
GO_RET(result, "digest fail(%08x)", result);
}
}
ali_hmac_copy_context(hmac_ctx, hmac_ctx);
ali_hmac_reset(hmac_ctx);
CRYPT_FREE(hmac_ctx);
hmac_ctx = NULL;
if (type == SHA1) {
if (CRYPT_MEMCMP(md, hmac_sha1, SHA1_HASH_SIZE)) {
ali_crypto_print_data("hmac-sha1", md, SHA1_HASH_SIZE);
GO_RET(-1, "HMAC-SHA1 test fail!\n");
} else {
CRYPT_INF("HMAC-SHA1 test success!\n");
}
} else if (type == SHA224) {
if (CRYPT_MEMCMP(md, hmac_sha224, SHA224_HASH_SIZE)) {
ali_crypto_print_data("hmac-sha224", md, SHA224_HASH_SIZE);
GO_RET(-1, "HMAC-SHA224 test fail!\n");
} else {
CRYPT_INF("HMAC-SHA224 test success!\n");
}
} else if (type == SHA256) {
if (CRYPT_MEMCMP(md, hmac_sha256, SHA256_HASH_SIZE)) {
ali_crypto_print_data("hmac-sha256", md, SHA256_HASH_SIZE);
GO_RET(-1, "HMAC-SHA256 test fail!\n");
} else {
CRYPT_INF("HMAC-SHA256 test success!\n");
}
/* } else if (type == SHA384) {
if(CRYPT_MEMCMP(md, hmac_sha384, SHA384_HASH_SIZE)) {
ali_crypto_print_data("hmac-sha384", md,
SHA384_HASH_SIZE); GO_RET(-1, "HMAC-SHA384 test fail!\n"); } else
{ CRYPT_INF("HMAC-SHA384 test success!\n");
}
} else if (type == SHA512) {
if(CRYPT_MEMCMP(md, hmac_sha512, SHA512_HASH_SIZE)) {
ali_crypto_print_data("hmac-sha512", md,
SHA512_HASH_SIZE); GO_RET(-1, "HMAC-SHA512 test fail!\n"); } else
{ CRYPT_INF("HMAC-SHA512 test success!\n");
}
*/
} else if (type == MD5) {
if (CRYPT_MEMCMP(md, hmac_md5, MD5_HASH_SIZE)) {
ali_crypto_print_data("hmac-md5", md, MD5_HASH_SIZE);
GO_RET(-1, "HMAC-MD5 test fail!\n");
} else {
CRYPT_INF("HMAC-MD5 test success!\n");
}
}
}
return 0;
_OUT:
if (hmac_ctx) {
CRYPT_FREE(hmac_ctx);
}
return -1;
}

View file

@ -0,0 +1,51 @@
/**
* Copyright (C) 2017 The YunOS Project. All rights reserved.
*/
#include "ali_crypto_test.h"
int ali_crypto_rand_test(void)
{
uint32_t i = 0;
uint8_t seed[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
size_t seed_len = 16;
uint8_t tmp_buf[32];
uint8_t rand_buf[32];
size_t rand_len = 32;
ali_crypto_result result;
result = ali_seed(seed, seed_len);
if (result != ALI_CRYPTO_SUCCESS) {
PRINT_RET(-1, "ali_seed fail(%08x)\n", result);
}
/* for gcov coverage */
result = ali_rand_gen(NULL, rand_len);
if (result == ALI_CRYPTO_SUCCESS) {
PRINT_RET(-1, "gen rand fail(%08x)\n", result);
}
result = ali_rand_gen(rand_buf, rand_len);
if (result != ALI_CRYPTO_SUCCESS) {
PRINT_RET(-1, "gen rand fail(%08x)\n", result);
}
while (i++ < 10) {
CRYPT_MEMCPY(tmp_buf, rand_buf, rand_len);
result = ali_rand_gen(rand_buf, rand_len);
if (result != ALI_CRYPTO_SUCCESS) {
PRINT_RET(-1, "gen rand fail(%08x)\n", result);
}
if (!CRYPT_MEMCMP(tmp_buf, rand_buf, rand_len)) {
ali_crypto_print_data("tmp_buf", tmp_buf, rand_len);
ali_crypto_print_data("rand_buf", rand_buf, rand_len);
PRINT_RET(-1, "RAND test fail!\n");
}
}
CRYPT_INF("RAND test success!\n");
return 0;
}

View file

@ -0,0 +1,779 @@
/**
* Copyright (C) 2016 The YunOS Project. All rights reserved.
*/
#include "ali_crypto.h"
#include "ali_crypto_test.h"
#define RSA_KEY_LEN (128)
static uint8_t RSA_1024_N[128] = {
0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51, 0x87, 0xdc,
0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e, 0x36, 0xad, 0x52, 0xa4,
0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a, 0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56,
0xff, 0xed, 0xb1, 0x62, 0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3,
0x94, 0xdf, 0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab,
0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d, 0x5b, 0x2b,
0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77, 0xc0, 0x92, 0x1c, 0xb2,
0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59, 0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1,
0x05, 0xac, 0xc2, 0xd3, 0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38,
0x6b, 0x6f, 0x64, 0xc4, 0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8,
0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37
};
static uint8_t RSA_1024_E[3] = { 0x01, 0x00, 0x01 };
static uint8_t RSA_1024_D[128] = {
0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51, 0xca, 0x9b,
0xbb, 0xd0, 0xb4, 0x47, 0x71, 0xa1, 0x01, 0xaf, 0x88, 0x43, 0x40, 0xae,
0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe, 0x92, 0xe8, 0x94, 0xa7, 0x24, 0xac,
0x3c, 0x56, 0x8c, 0x8f, 0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8,
0xc6, 0xa3, 0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44,
0x29, 0xfc, 0x4d, 0x9a, 0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10, 0xce, 0x70,
0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27, 0xa3, 0x95, 0x74, 0x50,
0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c, 0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c,
0x31, 0xb4, 0xbd, 0x2f, 0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3,
0x4f, 0x9e, 0x50, 0x3b, 0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc,
0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25
};
static int _rsa_test_gen_key(void)
{
int ret, result;
uint8_t rsa_n[RSA_KEY_LEN];
uint8_t rsa_e[RSA_KEY_LEN];
uint8_t rsa_d[RSA_KEY_LEN];
uint8_t rsa_p[RSA_KEY_LEN];
uint8_t rsa_q[RSA_KEY_LEN];
uint8_t rsa_dp[RSA_KEY_LEN];
uint8_t rsa_dq[RSA_KEY_LEN];
uint8_t rsa_qp[RSA_KEY_LEN];
uint32_t n_size = RSA_KEY_LEN;
uint32_t e_size = RSA_KEY_LEN;
uint32_t d_size = RSA_KEY_LEN;
uint32_t p_size = RSA_KEY_LEN;
uint32_t q_size = RSA_KEY_LEN;
uint32_t dp_size = RSA_KEY_LEN;
uint32_t dq_size = RSA_KEY_LEN;
uint32_t qp_size = RSA_KEY_LEN;
uint8_t * pub_key = NULL;
uint8_t * key_pair = NULL;
size_t pub_key_len, key_pair_len;
uint8_t src_data[RSA_KEY_LEN];
uint8_t ciphertext[RSA_KEY_LEN];
uint8_t plaintext[RSA_KEY_LEN];
size_t src_size, dst_size;
rsa_padding_t rsa_padding;
(void)result;
CRYPT_INF("rsa gen key test!\n");
/* for gcov coverage */
ret = ali_rsa_get_pubkey_size(RSA_KEY_LEN << 3, NULL);
if (ret == ALI_CRYPTO_SUCCESS) {
return -1;
}
/* for gcov coverage */
ret = ali_rsa_get_pubkey_size(255, &pub_key_len);
if (ret == ALI_CRYPTO_SUCCESS) {
return -1;
}
/* for gcov coverage */
ret = ali_rsa_get_keypair_size(RSA_KEY_LEN << 3, NULL);
if (ret == ALI_CRYPTO_SUCCESS) {
return -1;
}
/* for gcov coverage */
ret = ali_rsa_get_keypair_size(255, &key_pair_len);
if (ret == ALI_CRYPTO_SUCCESS) {
return -1;
}
/* for gcov coverage */
ret = ali_rsa_init_keypair(RSA_KEY_LEN << 3, rsa_n, n_size, rsa_e, e_size,
rsa_d, d_size, NULL, 0, NULL, 0, NULL, 0, NULL,
0, NULL, 0, NULL);
if (ret == ALI_CRYPTO_SUCCESS) {
return -1;
}
/* for gcov coverage */
ret =
ali_rsa_init_pubkey(RSA_KEY_LEN << 3, rsa_n, n_size, rsa_e, e_size, NULL);
if (ret == ALI_CRYPTO_SUCCESS) {
return -1;
}
/* for gcov coverage */
ret =
ali_rsa_init_pubkey(RSA_KEY_LEN << 3, rsa_n, n_size, rsa_e, e_size, NULL);
if (ret == ALI_CRYPTO_SUCCESS) {
return -1;
}
ret = ali_rsa_get_pubkey_size(RSA_KEY_LEN << 3, &pub_key_len);
if (ret != ALI_CRYPTO_SUCCESS) {
PRINT_RET(-1, "init_key: get pubkey size fail(%08x)\n", ret)
}
ret = ali_rsa_get_keypair_size(RSA_KEY_LEN << 3, &key_pair_len);
if (ret != ALI_CRYPTO_SUCCESS) {
PRINT_RET(-1, "init_key: get keypair size fail(%08x)\n", ret)
}
pub_key = CRYPT_MALLOC(pub_key_len);
if (pub_key == NULL) {
GO_RET(-1, "init_key: malloc(%d) fail\n", (int)pub_key_len);
}
key_pair = CRYPT_MALLOC(key_pair_len);
if (pub_key == NULL) {
GO_RET(-1, "init_key: malloc(%d) fail\n", (int)pub_key_len);
}
/* for gcov coverage */
ret = ali_rsa_gen_keypair(RSA_KEY_LEN << 3, NULL, 0, NULL);
if (ret == ALI_CRYPTO_SUCCESS) {
GO_RET(ALI_CRYPTO_ERROR, "ali_rsa_gen_keypair: not expect\n");
}
ret =
ali_rsa_gen_keypair(RSA_KEY_LEN << 3, NULL, 0, (rsa_keypair_t *)key_pair);
if (ret != ALI_CRYPTO_SUCCESS) {
GO_RET(-1, "init_key: gen keypair fail(%08x)\n", ret);
}
/* for gcov coverage */
ret = ali_rsa_get_key_attr(RSA_MODULUS, NULL, rsa_n, (size_t *)&n_size);
if (ret == ALI_CRYPTO_SUCCESS) {
GO_RET(ALI_CRYPTO_ERROR, "ali_rsa_get_key_attr: not expect\n");
}
/* for gcov coverage */
ret = ali_rsa_get_key_attr((rsa_key_attr_t)-1, (rsa_keypair_t *)key_pair,
rsa_n, (size_t *)&n_size);
if (ret == ALI_CRYPTO_SUCCESS) {
GO_RET(ALI_CRYPTO_ERROR, "ali_rsa_get_key_attr: not expect\n");
}
/* get key attrs */
ret = ali_rsa_get_key_attr(RSA_MODULUS, (rsa_keypair_t *)key_pair, rsa_n,
(size_t *)&n_size);
if (ret != ALI_CRYPTO_SUCCESS) {
goto _OUT;
}
ret = ali_rsa_get_key_attr(RSA_PUBLIC_EXPONENT, (rsa_keypair_t *)key_pair,
rsa_e, (size_t *)&e_size);
if (ret != ALI_CRYPTO_SUCCESS) {
goto _OUT;
}
ret = ali_rsa_get_key_attr(RSA_PRIVATE_EXPONENT, (rsa_keypair_t *)key_pair,
rsa_d, (size_t *)&d_size);
if (ret != ALI_CRYPTO_SUCCESS) {
goto _OUT;
}
ret = ali_rsa_get_key_attr(RSA_PRIME1, (rsa_keypair_t *)key_pair, rsa_p,
(size_t *)&p_size);
if (ret != ALI_CRYPTO_SUCCESS) {
goto _OUT;
}
ret = ali_rsa_get_key_attr(RSA_PRIME2, (rsa_keypair_t *)key_pair, rsa_q,
(size_t *)&q_size);
if (ret != ALI_CRYPTO_SUCCESS) {
goto _OUT;
}
ret = ali_rsa_get_key_attr(RSA_EXPONENT1, (rsa_keypair_t *)key_pair, rsa_dp,
(size_t *)&dp_size);
if (ret != ALI_CRYPTO_SUCCESS) {
goto _OUT;
}
ret = ali_rsa_get_key_attr(RSA_EXPONENT2, (rsa_keypair_t *)key_pair, rsa_dq,
(size_t *)&dq_size);
if (ret != ALI_CRYPTO_SUCCESS) {
goto _OUT;
}
ret = ali_rsa_get_key_attr(RSA_COEFFICIENT, (rsa_keypair_t *)key_pair,
rsa_qp, (size_t *)&qp_size);
if (ret != ALI_CRYPTO_SUCCESS) {
goto _OUT;
}
/* for gcov coverage */
ret = ali_rsa_init_keypair(RSA_KEY_LEN << 3, rsa_n, 129, rsa_e, e_size,
rsa_d, d_size, NULL, 0, NULL, 0, NULL, 0, NULL,
0, NULL, 0, (rsa_keypair_t *)key_pair);
if (ret == ALI_CRYPTO_SUCCESS) {
GO_RET(ALI_CRYPTO_ERROR, "ali_rsa_init_keypair: not expect\n");
}
/* for gcov coverage */
ret = ali_rsa_init_keypair(RSA_KEY_LEN << 3, rsa_n, n_size, rsa_e, e_size,
rsa_d, d_size, rsa_p, p_size, rsa_q, q_size,
rsa_dp, dp_size, rsa_dq, dq_size, rsa_qp,
qp_size, (rsa_keypair_t *)key_pair);
if (ret != ALI_CRYPTO_SUCCESS) {
goto _OUT;
}
CRYPT_MEMSET(key_pair, 0, key_pair_len);
ret = ali_rsa_init_keypair(RSA_KEY_LEN << 3, rsa_n, n_size, rsa_e, e_size,
rsa_d, d_size, NULL, 0, NULL, 0, NULL, 0, NULL,
0, NULL, 0, (rsa_keypair_t *)key_pair);
if (ret != ALI_CRYPTO_SUCCESS) {
GO_RET(ret, "init_key: init keypair fail(%08x)\n", ret);
}
/* for gcov coverage */
ret = ali_rsa_init_pubkey(RSA_KEY_LEN << 3, rsa_n, 129, rsa_e, e_size,
(rsa_pubkey_t *)pub_key);
if (ret == ALI_CRYPTO_SUCCESS) {
GO_RET(ALI_CRYPTO_ERROR, "ali_rsa_init_pubkey: not expect\n");
}
CRYPT_MEMSET(pub_key, 0, pub_key_len);
ret = ali_rsa_init_pubkey(RSA_KEY_LEN << 3, rsa_n, n_size, rsa_e, e_size,
(rsa_pubkey_t *)pub_key);
if (ret != ALI_CRYPTO_SUCCESS) {
GO_RET(ALI_CRYPTO_ERROR, "init_key: init pub_key fail(%08x)\n", ret);
}
rsa_padding.type = RSAES_PKCS1_V1_5;
/* for gcov coverage */
src_size = RSA_KEY_LEN;
dst_size = RSA_KEY_LEN;
ret = ali_rsa_public_encrypt((const rsa_pubkey_t *)NULL, src_data, src_size,
ciphertext, &dst_size, rsa_padding);
if (ret == ALI_CRYPTO_SUCCESS) {
GO_RET(ALI_CRYPTO_ERROR, "ali_rsa_public_encrypt: not expect\n");
}
/* for gcov coverage */
ret = ali_rsa_private_decrypt(NULL, ciphertext, RSA_KEY_LEN, plaintext,
&dst_size, rsa_padding);
if (ret == ALI_CRYPTO_SUCCESS) {
GO_RET(ALI_CRYPTO_ERROR, "ali_rsa_private_decrypt: not expect\n");
}
CRYPT_MEMSET(&rsa_padding, 0, sizeof(rsa_padding_t));
rsa_padding.type = RSAES_PKCS1_V1_5;
src_size = RSA_KEY_LEN - 11;
CRYPT_MEMSET(src_data, 0xa, src_size);
dst_size = RSA_KEY_LEN;
ret = ali_rsa_public_encrypt((const rsa_pubkey_t *)pub_key, src_data,
src_size, ciphertext, &dst_size, rsa_padding);
if (ret != ALI_CRYPTO_SUCCESS) {
GO_RET(ALI_CRYPTO_ERROR, "ali_rsa_public_encrypt: rsa_v1_5 fail %d\n",
ret);
}
ret =
ali_rsa_private_decrypt((const rsa_keypair_t *)key_pair, ciphertext,
RSA_KEY_LEN, plaintext, &dst_size, rsa_padding);
if (ret != ALI_CRYPTO_SUCCESS || dst_size != src_size) {
GO_RET(ALI_CRYPTO_ERROR, "ali_rsa_private_decrypt: rsa_v1_5 fail %d\n",
ret);
}
if (CRYPT_MEMCMP(src_data, plaintext, src_size)) {
ali_crypto_print_data("pliantext", plaintext, src_size);
ali_crypto_print_data("ciphertext", ciphertext, dst_size);
PRINT_RET(-1, "RSA encrypt/decrypt with PKCS1_V1_5 test fail!\n");
} else {
CRYPT_INF("RSA encrypt/decrypt with PKCS1_V1_5 test success!\n");
}
CRYPT_FREE(pub_key);
CRYPT_FREE(key_pair);
return 0;
_OUT:
if (pub_key) {
CRYPT_FREE(pub_key);
}
if (key_pair) {
CRYPT_FREE(key_pair);
}
return -1;
}
static int _ali_crypto_init_key(rsa_keypair_t **keypair, rsa_pubkey_t **pubkey)
{
ali_crypto_result ret, result;
uint8_t rsa_n[RSA_KEY_LEN];
uint8_t rsa_e[RSA_KEY_LEN];
uint8_t rsa_d[RSA_KEY_LEN];
uint32_t n_size = RSA_KEY_LEN;
uint32_t e_size = RSA_KEY_LEN;
uint32_t d_size = RSA_KEY_LEN;
uint8_t * pub_key = NULL;
uint8_t * key_pair = NULL;
size_t pub_key_len, key_pair_len;
(void)e_size;
(void)rsa_d;
(void)rsa_e;
(void)rsa_n;
(void)result;
if (keypair == NULL || pubkey == NULL) {
PRINT_RET(-1, "init_key: invalid input args!\n");
}
ret = ali_rsa_get_pubkey_size(RSA_KEY_LEN << 3, &pub_key_len);
if (ret != ALI_CRYPTO_SUCCESS) {
PRINT_RET(-1, "init_key: get pubkey size fail(%08x)\n", ret);
}
ret = ali_rsa_get_keypair_size(RSA_KEY_LEN << 3, &key_pair_len);
if (ret != ALI_CRYPTO_SUCCESS) {
PRINT_RET(-1, "init_key: get keypair size fail(%08x)\n", ret);
}
pub_key = CRYPT_MALLOC(pub_key_len);
if (pub_key == NULL) {
GO_RET(-1, "init_key: malloc(%d) fail\n", (int)pub_key_len);
}
key_pair = CRYPT_MALLOC(key_pair_len);
if (pub_key == NULL) {
GO_RET(-1, "init_key: malloc(%d) fail\n", (int)pub_key_len);
}
#if 0
ret = ali_rsa_gen_keypair(RSA_KEY_LEN << 3, NULL, 0, (rsa_keypair_t *)key_pair);
if (ret != ALI_CRYPTO_SUCCESS) {
CRYPT_ERR("init_key: gen keypair fail(%08x)\n", ret);
goto _OUT;
}
/* get key attrs */
ret = ali_rsa_get_key_attr(RSA_MODULUS,
(rsa_keypair_t *)key_pair, rsa_n, (size_t *)&n_size);
if (ret != ALI_CRYPTO_SUCCESS) {
goto _OUT;
}
ret = ali_rsa_get_key_attr(RSA_PUBLIC_EXPONENT,
(rsa_keypair_t *)key_pair, rsa_e, (size_t *)&e_size);
if (ret != ALI_CRYPTO_SUCCESS) {
goto _OUT;
}
ret = ali_rsa_get_key_attr(RSA_PRIVATE_EXPONENT,
(rsa_keypair_t *)key_pair, rsa_d, (size_t *)&d_size);
if (ret != ALI_CRYPTO_SUCCESS) {
goto _OUT;
}
CRYPT_MEMSET(key_pair, 0, key_pair_len);
ret = ali_rsa_init_keypair(RSA_KEY_LEN << 3,
rsa_n, n_size, rsa_e, e_size, rsa_d, d_size,
NULL , 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, (rsa_keypair_t *)key_pair);
if (ret != ALI_CRYPTO_SUCCESS) {
CRYPT_ERR("init_key: init keypair fail(%08x)\n", ret);
goto _OUT;
}
CRYPT_MEMSET(pub_key, 0, pub_key_len);
ret = ali_rsa_init_pubkey(RSA_KEY_LEN << 3,
rsa_n, n_size, rsa_e, e_size, (rsa_pubkey_t *)pub_key);
if (ret != ALI_CRYPTO_SUCCESS) {
CRYPT_ERR("init_key: init pub_key fail(%08x)\n", ret);
goto _OUT;
}
#else
CRYPT_MEMSET(key_pair, 0, key_pair_len);
ret = ali_rsa_init_keypair(RSA_KEY_LEN << 3, RSA_1024_N, n_size, RSA_1024_E,
3, RSA_1024_D, d_size, NULL, 0, NULL, 0, NULL, 0,
NULL, 0, NULL, 0, (rsa_keypair_t *)key_pair);
if (ret != ALI_CRYPTO_SUCCESS) {
GO_RET(-1, "init_key: init keypair fail(%08x)\n", ret);
}
CRYPT_MEMSET(pub_key, 0, pub_key_len);
ret = ali_rsa_init_pubkey(RSA_KEY_LEN << 3, RSA_1024_N, n_size, RSA_1024_E,
3, (rsa_pubkey_t *)pub_key);
if (ret != ALI_CRYPTO_SUCCESS) {
GO_RET(-1, "init_key: init pub_key fail(%08x)\n", ret);
}
#endif
*pubkey = (rsa_pubkey_t *)pub_key;
*keypair = (rsa_keypair_t *)key_pair;
return 0;
_OUT:
if (pub_key) {
CRYPT_FREE(pub_key);
}
if (key_pair) {
CRYPT_FREE(key_pair);
}
return -1;
}
#if 0
static int _ali_crypto_encrypt_decrypt_nopad(
rsa_pubkey_t *pubkey, rsa_keypair_t *keypair)
{
ali_crypto_result ret;
uint8_t src_data[RSA_KEY_LEN];
uint8_t plaintext[RSA_KEY_LEN];
uint8_t ciphertext[RSA_KEY_LEN];
size_t src_size, dst_size;
rsa_padding_t rsa_padding;
if (pubkey == NULL || keypair == NULL) {
CRYPT_ERR("rsa_nopad: invalid input args!\n");
return -1;
}
rsa_padding.type = RSA_NOPAD;
src_size = RSA_KEY_LEN;
CRYPT_MEMSET(src_data, 0xa, src_size);
dst_size = RSA_KEY_LEN;
ret = ali_rsa_public_encrypt(pubkey, src_data, src_size,
ciphertext, &dst_size, rsa_padding);
if (ret != ALI_CRYPTO_SUCCESS) {
CRYPT_ERR("rsa_nopad: public encrypt fail(%08x)\n", ret);
return -1;
}
ret = ali_rsa_private_decrypt(keypair, ciphertext, RSA_KEY_LEN,
plaintext, &dst_size, rsa_padding);
if (ret != ALI_CRYPTO_SUCCESS || dst_size != src_size) {
CRYPT_ERR("rsa_nopad: private decrypt fail(%08x)\n", ret);
return -1;
}
if (CRYPT_MEMCMP(src_data, plaintext, src_size)) {
CRYPT_ERR("RSA encrypt/decrypt with no-padding test fail!\n");
ali_crypto_print_data("pliantext", plaintext, src_size);
ali_crypto_print_data("ciphertext", ciphertext, dst_size);
} else {
CRYPT_INF("RSA encrypt/decrypt with no-padding test success!\n");
}
return 0;
}
#endif
static int _ali_crypto_encrypt_decrypt_v1_5(rsa_pubkey_t * pubkey,
rsa_keypair_t *keypair)
{
ali_crypto_result ret;
uint8_t src_data[RSA_KEY_LEN];
uint8_t plaintext[RSA_KEY_LEN];
uint8_t ciphertext[RSA_KEY_LEN];
size_t src_size, dst_size;
rsa_padding_t rsa_padding;
if (pubkey == NULL || keypair == NULL) {
PRINT_RET(-1, "rsa_v1_5: invalid input args!\n");
}
CRYPT_MEMSET(&rsa_padding, 0, sizeof(rsa_padding_t));
rsa_padding.type = RSAES_PKCS1_V1_5;
src_size = RSA_KEY_LEN - 11;
CRYPT_MEMSET(src_data, 0xa, src_size);
dst_size = RSA_KEY_LEN;
ret = ali_rsa_public_encrypt(pubkey, src_data, src_size, ciphertext,
&dst_size, rsa_padding);
if (ret != ALI_CRYPTO_SUCCESS) {
PRINT_RET(-1, "rsa_v1_5: public encrypt fail(%08x)\n", ret);
}
/* for gcov coverage */
ret = ali_rsa_public_encrypt(pubkey, src_data, RSA_KEY_LEN, ciphertext,
&dst_size, rsa_padding);
if (ret == ALI_CRYPTO_SUCCESS) {
return -1;
}
ret = ali_rsa_private_decrypt(keypair, ciphertext, RSA_KEY_LEN, plaintext,
&dst_size, rsa_padding);
if (ret != ALI_CRYPTO_SUCCESS || dst_size != src_size) {
PRINT_RET(-1, "rsa_v1_5: public decrypt fail(%08x)\n", ret);
}
if (CRYPT_MEMCMP(src_data, plaintext, src_size)) {
ali_crypto_print_data("pliantext", plaintext, src_size);
ali_crypto_print_data("ciphertext", ciphertext, dst_size);
PRINT_RET(-1, "RSA encrypt/decrypt with PKCS1_V1_5 test fail!\n");
} else {
CRYPT_INF("RSA encrypt/decrypt with PKCS1_V1_5 test success!\n");
}
return 0;
}
static int _ali_crypto_encrypt_decrypt_oaep(rsa_pubkey_t * pubkey,
rsa_keypair_t *keypair)
{
ali_crypto_result ret;
hash_type_t hash_type;
rsa_padding_t rsa_padding;
uint8_t src_data[RSA_KEY_LEN];
uint8_t plaintext[RSA_KEY_LEN];
uint8_t ciphertext[RSA_KEY_LEN];
size_t src_size, dst_size;
// uint8_t lparam[] = {0xe1, 0xe2, 0xe2, 0xe4, 0xe5};
if (pubkey == NULL || keypair == NULL) {
CRYPT_ERR("rsa_v1_5: invalid input args!\n");
PRINT_RET(-1, "rsa_v1_5: invalid input args!\n");
}
rsa_padding.type = RSAES_PKCS1_OAEP_MGF1;
for (hash_type = SHA1; hash_type <= MD5; hash_type++) {
if (hash_type == SHA512 || hash_type == SHA384) {
CRYPT_INF("rsa oeap not support hash 384 512\n");
continue;
}
/*
if (2*HASH_SIZE(hash_type) >= RSA_KEY_LEN - 2) {
continue;
}
*/
src_size = RSA_KEY_LEN - 2 * HASH_SIZE(hash_type) - 2;
CRYPT_MEMSET(src_data, 0xa, src_size);
/* without lparam */
rsa_padding.pad.rsaes_oaep.type = hash_type;
dst_size = RSA_KEY_LEN;
ret = ali_rsa_public_encrypt(pubkey, src_data, src_size, ciphertext,
&dst_size, rsa_padding);
if (ret != ALI_CRYPTO_SUCCESS) {
PRINT_RET(
-1, "rsa_oaep: public encrypt(without lparam) fail(%08x)\n", ret);
}
ret = ali_rsa_private_decrypt(keypair, ciphertext, RSA_KEY_LEN,
plaintext, &dst_size, rsa_padding);
if (ret != ALI_CRYPTO_SUCCESS || dst_size != src_size) {
PRINT_RET(-1,
"rsa_oaep: private decrypt(without lparam) fail(%08x)\n",
ret);
}
if (CRYPT_MEMCMP(src_data, plaintext, src_size)) {
ali_crypto_print_data("pliantext", plaintext, src_size);
ali_crypto_print_data("ciphertext", ciphertext, dst_size);
PRINT_RET(-1, "RSA encrypt/decrypt with PKCS1_OAEP(without lparam) "
"test fail!\n");
} else {
CRYPT_INF("RSA encrypt/decrypt with PKCS1_OAEP(without lparam) "
"test success!\n");
}
/* with lparam */
rsa_padding.pad.rsaes_oaep.type = hash_type;
dst_size = RSA_KEY_LEN;
ret = ali_rsa_public_encrypt(pubkey, src_data, src_size, ciphertext,
&dst_size, rsa_padding);
if (ret != ALI_CRYPTO_SUCCESS) {
PRINT_RET(-1, "rsa_oaep: public encrypt(with lparam) fail(%08x)\n",
ret);
}
ret = ali_rsa_private_decrypt(keypair, ciphertext, RSA_KEY_LEN,
plaintext, &dst_size, rsa_padding);
if (ret != ALI_CRYPTO_SUCCESS || dst_size != src_size) {
PRINT_RET(-1, "rsa_oaep: private decrypt(with lparam) fail(%08x)\n",
ret);
}
if (CRYPT_MEMCMP(src_data, plaintext, src_size)) {
ali_crypto_print_data("pliantext", plaintext, src_size);
ali_crypto_print_data("ciphertext", ciphertext, dst_size);
PRINT_RET(
-1,
"RSA encrypt/decrypt with PKCS1_OAEP(with lparam) test fail!\n");
} else {
CRYPT_INF("RSA encrypt/decrypt with PKCS1_OAEP(with lparam) test "
"success!\n");
}
}
return 0;
}
static int _ali_crypto_sign_verify_v1_5(rsa_pubkey_t * pubkey,
rsa_keypair_t *keypair)
{
bool result1, result2;
ali_crypto_result ret;
hash_type_t hash_type;
uint8_t src_data[RSA_KEY_LEN];
uint8_t signature[RSA_KEY_LEN];
size_t src_size, dst_size;
rsa_padding_t rsa_padding;
if (pubkey == NULL || keypair == NULL) {
PRINT_RET(-1, "rsa_v1_5: invalid input args!\n");
}
rsa_padding.type = RSASSA_PKCS1_V1_5;
for (hash_type = SHA1; hash_type <= MD5; hash_type++) {
rsa_padding.pad.rsassa_v1_5.type = hash_type;
if (hash_type == SHA512 || hash_type == SHA384) {
CRYPT_INF("mbedtls rsa V1.5 not support hash 384 512\n");
continue;
}
#if 0
if (HASH_SIZE(hash_type) + 11 > RSA_KEY_LEN) {
continue;
}
#endif
src_size = HASH_SIZE(hash_type);
CRYPT_MEMSET(src_data, 0xa, src_size);
dst_size = RSA_KEY_LEN;
ret = ali_rsa_sign(keypair, src_data, src_size, signature, &dst_size,
rsa_padding);
if (ret != ALI_CRYPTO_SUCCESS) {
PRINT_RET(-1, "rsa_v1_5: sign fail(%08x)\n", ret);
}
ret = ali_rsa_verify(pubkey, src_data, src_size, signature, dst_size,
rsa_padding, &result1);
if (ret != ALI_CRYPTO_SUCCESS) {
PRINT_RET(-1, "rsa_v1_5: verify fail(%08x)\n", ret);
}
src_data[0] = src_data[0] ^ 0x1;
ret = ali_rsa_verify(pubkey, src_data, src_size, signature, dst_size,
rsa_padding, &result2);
if (ret == ALI_CRYPTO_SUCCESS) {
PRINT_RET(-1, "rsa_v1_5: verify fail(%08x)\n", ret);
}
if (result1 == true && result2 == false) {
CRYPT_INF("RSA sign/verify with PKCS1_V1_5 success!\n");
} else {
PRINT_RET(-1, "RSA sign/verify with PKCS1_V1_5 fail!\n");
}
}
return 0;
}
static int _ali_crypto_sign_verify_pss(rsa_pubkey_t * pubkey,
rsa_keypair_t *keypair)
{
bool result1, result2;
ali_crypto_result ret;
hash_type_t hash_type;
uint8_t src_data[RSA_KEY_LEN];
uint8_t signature[RSA_KEY_LEN];
size_t src_size, dst_size;
rsa_padding_t rsa_padding;
if (pubkey == NULL || keypair == NULL) {
PRINT_RET(-1, "rsa_pss: invalid input args!\n");
}
rsa_padding.type = RSASSA_PKCS1_PSS_MGF1;
for (hash_type = SHA1; hash_type <= MD5; hash_type++) {
rsa_padding.pad.rsassa_pss.type = hash_type;
rsa_padding.pad.rsassa_pss.salt_len = 28;
if (hash_type == SHA512 || hash_type == SHA384) {
CRYPT_INF("mbedtls rsa pss not support hash 512\n");
continue;
}
#if 0
if (HASH_SIZE(hash_type) + 28 + 2 > RSA_KEY_LEN) {
continue;
}
#endif
src_size = HASH_SIZE(hash_type);
CRYPT_MEMSET(src_data, 0xa, src_size);
dst_size = RSA_KEY_LEN;
ret = ali_rsa_sign(keypair, src_data, src_size, signature, &dst_size,
rsa_padding);
if (ret != ALI_CRYPTO_SUCCESS) {
PRINT_RET(-1, "rsa_pss: sign fail(%08x)\n", ret);
}
ret = ali_rsa_verify(pubkey, src_data, src_size, signature, dst_size,
rsa_padding, &result1);
if (ret != ALI_CRYPTO_SUCCESS) {
PRINT_RET(-1, "rsa_pss: verify fail(%08x)\n", ret);
}
src_data[0] = src_data[0] ^ 0x1;
ret = ali_rsa_verify(pubkey, src_data, src_size, signature, dst_size,
rsa_padding, &result2);
if (ret == ALI_CRYPTO_SUCCESS) {
PRINT_RET(-1, "rsa_pss: verify fail(%08x)\n", ret);
}
if (result1 == true && result2 == false) {
CRYPT_INF("RSA sign/verify with PKCS1_PSS_MGF1 success!\n");
} else {
PRINT_RET(-1, "RSA sign/verify with PKCS1_PSS_MGF1 fail!\n");
}
}
return 0;
}
int ali_crypto_rsa_test(void)
{
int ret;
rsa_pubkey_t * pubkey = NULL;
rsa_keypair_t *keypair = NULL;
ret = _rsa_test_gen_key();
if (ret < 0) {
goto _out;
}
ret = _ali_crypto_init_key(&keypair, &pubkey);
if (ret < 0) {
goto _out;
}
/* TODO */
#if 0
ret = _ali_crypto_encrypt_decrypt_nopad(pubkey, keypair);
if (ret < 0) {
goto _out;
}
#endif
ret = _ali_crypto_encrypt_decrypt_v1_5(pubkey, keypair);
if (ret < 0) {
goto _out;
}
ret = _ali_crypto_encrypt_decrypt_oaep(pubkey, keypair);
if (ret < 0) {
goto _out;
}
ret = _ali_crypto_sign_verify_v1_5(pubkey, keypair);
if (ret < 0) {
goto _out;
}
ret = _ali_crypto_sign_verify_pss(pubkey, keypair);
if (ret < 0) {
goto _out;
}
_out:
if (pubkey) {
CRYPT_FREE(pubkey);
}
if (keypair) {
CRYPT_FREE(keypair);
}
if (0 == ret) {
CRYPT_INF("================ALI crypto test SUCCESS!\n");
} else {
CRYPT_INF("================ALI crypto test FAIL!\n");
}
return ret;
}

View file

@ -0,0 +1,51 @@
/**
* Copyright (C) 2017 The YunOS Project. All rights reserved.
*/
#ifndef _ALI_CRYPTO_TEST_H_
#define _ALI_CRYPTO_TEST_H_
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "ali_crypto.h"
#define CRYPT_ERR(_f, ...) \
printf("E %s %d: "_f, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define CRYPT_INF(_f, ...) \
printf("I %s %d: "_f, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#ifdef MBEDTLS_IOT_PLAT_AOS
#include <aos/kernel.h>
#define CRYPT_MALLOC aos_malloc
#define CRYPT_FREE aos_free
#else
#define CRYPT_MALLOC malloc
#define CRYPT_FREE free
#endif
#define CRYPT_MEMSET memset
#define CRYPT_MEMCPY memcpy
#define CRYPT_MEMCMP memcmp
#define PRINT_RET(_ret, _f, ...) \
do { \
CRYPT_ERR(_f, ##__VA_ARGS__); \
return _ret; \
} while (0);
#define GO_RET(_ret, _f, ...) \
do { \
CRYPT_ERR(_f, ##__VA_ARGS__); \
result = _ret; \
goto _OUT; \
} while (0);
void ali_crypto_print_data(const char *name, uint8_t *data, size_t size);
int ali_crypto_hash_test(void);
int ali_crypto_hmac_test(void);
int ali_crypto_rand_test(void);
int ali_crypto_aes_test(void);
int ali_crypto_rsa_test(void);
#endif

View file

@ -0,0 +1,25 @@
CMakeCache.txt
CMakeFiles
CTestTestfile.cmake
cmake_install.cmake
Testing
Coverage
*.gcno
*.gcda
# generated by scripts/memory.sh
massif-*
# MSVC files generated by CMake:
/*.sln
/*.vcxproj
/*.filters
# MSVC build artifacts:
*.exe
*.pdb
*.ilk
*.lib
# CMake generates *.dir/ folders for in-tree builds (used by MSVC projects), ignore all of those:
*.dir/

View file

@ -0,0 +1,39 @@
language: c
compiler:
- clang
- gcc
sudo: false
cache: ccache
script:
- tests/scripts/recursion.pl library/*.c
- tests/scripts/check-generated-files.sh
- tests/scripts/check-doxy-blocks.pl
- tests/scripts/check-names.sh
- tests/scripts/doxygen.sh
- cmake -D CMAKE_BUILD_TYPE:String="Check" .
- make
- make test
- programs/test/selftest
- OSSL_NO_DTLS=1 tests/compat.sh
- tests/ssl-opt.sh -e '\(DTLS\|SCSV\).*openssl'
- tests/scripts/test-ref-configs.pl
- tests/scripts/curves.pl
- tests/scripts/key-exchanges.pl
after_failure:
- tests/scripts/travis-log-failure.sh
env:
global:
secure: "barHldniAfXyoWOD/vcO+E6/Xm4fmcaUoC9BeKW+LwsHqlDMLvugaJnmLXkSpkbYhVL61Hzf3bo0KPJn88AFc5Rkf8oYHPjH4adMnVXkf3B9ghHCgznqHsAH3choo6tnPxaFgOwOYmLGb382nQxfE5lUdvnM/W/psQjWt66A1+k="
addons:
apt:
packages:
- doxygen
- graphviz
coverity_scan:
project:
name: "ARMmbed/mbedtls"
notification_email: p.j.bakker@polarssl.org
build_command_prepend:
build_command: make
branch_pattern: coverity_scan

View file

@ -0,0 +1,166 @@
cmake_minimum_required(VERSION 2.6)
project("mbed TLS" C)
option(USE_PKCS11_HELPER_LIBRARY "Build mbed TLS with the pkcs11-helper library." OFF)
option(ENABLE_ZLIB_SUPPORT "Build mbed TLS with zlib library." OFF)
option(ENABLE_PROGRAMS "Build mbed TLS programs." ON)
option(UNSAFE_BUILD "Allow unsafe builds. These builds ARE NOT SECURE." OFF)
# the test suites currently have compile errors with MSVC
if(MSVC)
option(ENABLE_TESTING "Build mbed TLS tests." OFF)
else()
option(ENABLE_TESTING "Build mbed TLS tests." ON)
endif()
# Warning string - created as a list for compatibility with CMake 2.8
set(WARNING_BORDER "*******************************************************\n")
set(NULL_ENTROPY_WARN_L1 "**** WARNING! MBEDTLS_TEST_NULL_ENTROPY defined!\n")
set(NULL_ENTROPY_WARN_L2 "**** THIS BUILD HAS NO DEFINED ENTROPY SOURCES\n")
set(NULL_ENTROPY_WARN_L3 "**** AND IS *NOT* SUITABLE FOR PRODUCTION USE\n")
set(NULL_ENTROPY_WARNING "${WARNING_BORDER}"
"${NULL_ENTROPY_WARN_L1}"
"${NULL_ENTROPY_WARN_L2}"
"${NULL_ENTROPY_WARN_L3}"
"${WARNING_BORDER}")
find_package(Perl)
if(PERL_FOUND)
# If NULL Entropy is configured, display an appropriate warning
execute_process(COMMAND ${PERL_EXECUTABLE} ${CMAKE_SOURCE_DIR}/scripts/config.pl -f ${CMAKE_SOURCE_DIR}/include/mbedtls/config.h get MBEDTLS_TEST_NULL_ENTROPY
RESULT_VARIABLE result)
if(${result} EQUAL 0)
message(WARNING ${NULL_ENTROPY_WARNING})
if(NOT UNSAFE_BUILD)
message(FATAL_ERROR "\
\n\
Warning! You have enabled MBEDTLS_TEST_NULL_ENTROPY. \
This option is not safe for production use and negates all security \
It is intended for development use only. \
\n\
To confirm you want to build with this option, re-run cmake with the \
option: \n\
cmake -DUNSAFE_BUILD=ON ")
return()
endif()
endif()
endif()
set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE}
CACHE STRING "Choose the type of build: None Debug Release Coverage ASan ASanDbg MemSan MemSanDbg Check CheckFull"
FORCE)
string(REGEX MATCH "Clang" CMAKE_COMPILER_IS_CLANG "${CMAKE_C_COMPILER_ID}")
if(CMAKE_COMPILER_IS_GNUCC)
# some warnings we want are not available with old GCC versions
# note: starting with CMake 2.8 we could use CMAKE_C_COMPILER_VERSION
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
OUTPUT_VARIABLE GCC_VERSION)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -W -Wdeclaration-after-statement -Wwrite-strings")
if (GCC_VERSION VERSION_GREATER 4.5 OR GCC_VERSION VERSION_EQUAL 4.5)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wlogical-op")
endif()
if (GCC_VERSION VERSION_GREATER 4.8 OR GCC_VERSION VERSION_EQUAL 4.8)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wshadow")
endif()
set(CMAKE_C_FLAGS_RELEASE "-O2")
set(CMAKE_C_FLAGS_DEBUG "-O0 -g3")
set(CMAKE_C_FLAGS_COVERAGE "-O0 -g3 --coverage")
set(CMAKE_C_FLAGS_ASAN "-Werror -fsanitize=address -fno-common -O3")
set(CMAKE_C_FLAGS_ASANDBG "-Werror -fsanitize=address -fno-common -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls ")
set(CMAKE_C_FLAGS_CHECK "-Werror -Os")
set(CMAKE_C_FLAGS_CHECKFULL "${CMAKE_C_FLAGS_CHECK} -Wcast-qual")
endif(CMAKE_COMPILER_IS_GNUCC)
if(CMAKE_COMPILER_IS_CLANG)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -W -Wdeclaration-after-statement -Wwrite-strings -Wpointer-arith -Wimplicit-fallthrough -Wshadow")
set(CMAKE_C_FLAGS_RELEASE "-O2")
set(CMAKE_C_FLAGS_DEBUG "-O0 -g3")
set(CMAKE_C_FLAGS_COVERAGE "-O0 -g3 --coverage")
set(CMAKE_C_FLAGS_ASAN "-Werror -fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover -O3")
set(CMAKE_C_FLAGS_ASANDBG "-Werror -fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls ")
set(CMAKE_C_FLAGS_MEMSAN "-Werror -fsanitize=memory -O3")
set(CMAKE_C_FLAGS_MEMSANDBG "-Werror -fsanitize=memory -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize-memory-track-origins=2")
set(CMAKE_C_FLAGS_CHECK "-Werror -Os")
endif(CMAKE_COMPILER_IS_CLANG)
if(MSVC)
# Strictest warnings, and treat as errors
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W3")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX")
endif(MSVC)
if(CMAKE_BUILD_TYPE STREQUAL "Coverage")
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG)
set(CMAKE_SHARED_LINKER_FLAGS "--coverage")
endif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG)
endif(CMAKE_BUILD_TYPE STREQUAL "Coverage")
if(LIB_INSTALL_DIR)
else()
set(LIB_INSTALL_DIR lib)
endif()
include_directories(include/)
if(ENABLE_ZLIB_SUPPORT)
find_package(ZLIB)
if(ZLIB_FOUND)
include_directories(${ZLIB_INCLUDE_DIR})
endif(ZLIB_FOUND)
endif(ENABLE_ZLIB_SUPPORT)
add_subdirectory(library)
add_subdirectory(include)
if(ENABLE_PROGRAMS)
add_subdirectory(programs)
endif()
ADD_CUSTOM_TARGET(apidoc
COMMAND doxygen doxygen/mbedtls.doxyfile
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
if(ENABLE_TESTING)
enable_testing()
add_subdirectory(tests)
# additional convenience targets for Unix only
if(UNIX)
ADD_CUSTOM_TARGET(covtest
COMMAND make test
COMMAND programs/test/selftest
COMMAND tests/compat.sh
COMMAND tests/ssl-opt.sh
)
ADD_CUSTOM_TARGET(lcov
COMMAND rm -rf Coverage
COMMAND lcov --capture --initial --directory library/CMakeFiles/mbedtls.dir -o files.info
COMMAND lcov --capture --directory library/CMakeFiles/mbedtls.dir -o tests.info
COMMAND lcov --add-tracefile files.info --add-tracefile tests.info -o all.info
COMMAND lcov --remove all.info -o final.info '*.h'
COMMAND gendesc tests/Descriptions.txt -o descriptions
COMMAND genhtml --title "mbed TLS" --description-file descriptions --keep-descriptions --legend --no-branch-coverage -o Coverage final.info
COMMAND rm -f files.info tests.info all.info final.info descriptions
)
ADD_CUSTOM_TARGET(memcheck
COMMAND sed -i.bak s+/usr/bin/valgrind+`which valgrind`+ DartConfiguration.tcl
COMMAND ctest -O memcheck.log -D ExperimentalMemCheck
COMMAND tail -n1 memcheck.log | grep 'Memory checking results:' > /dev/null
COMMAND rm -f memcheck.log
COMMAND mv DartConfiguration.tcl.bak DartConfiguration.tcl
)
endif(UNIX)
endif()

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,4 @@
Site: localhost
BuildName: mbed TLS-test
CoverageCommand: /usr/bin/gcov
MemoryCheckCommand: /usr/bin/valgrind

View file

@ -0,0 +1,2 @@
Unless specifically indicated otherwise in a file, files are licensed
under the Apache 2.0 license, as can be found in: apache-2.0.txt

View file

@ -0,0 +1,110 @@
DESTDIR=/usr/local
PREFIX=mbedtls_
.SILENT:
.PHONY: all no_test programs lib tests install uninstall clean test check covtest lcov apidoc apidoc_clean
all: programs tests
$(MAKE) post_build
no_test: programs
programs: lib
$(MAKE) -C programs
lib:
$(MAKE) -C library
tests: lib
$(MAKE) -C tests
ifndef WINDOWS
install: no_test
mkdir -p $(DESTDIR)/include/mbedtls
cp -r include/mbedtls $(DESTDIR)/include
mkdir -p $(DESTDIR)/lib
cp -RP library/libmbedtls.* $(DESTDIR)/lib
cp -RP library/libmbedx509.* $(DESTDIR)/lib
cp -RP library/libmbedcrypto.* $(DESTDIR)/lib
mkdir -p $(DESTDIR)/bin
for p in programs/*/* ; do \
if [ -x $$p ] && [ ! -d $$p ] ; \
then \
f=$(PREFIX)`basename $$p` ; \
cp $$p $(DESTDIR)/bin/$$f ; \
fi \
done
uninstall:
rm -rf $(DESTDIR)/include/mbedtls
rm -f $(DESTDIR)/lib/libmbedtls.*
rm -f $(DESTDIR)/lib/libmbedx509.*
rm -f $(DESTDIR)/lib/libmbedcrypto.*
for p in programs/*/* ; do \
if [ -x $$p ] && [ ! -d $$p ] ; \
then \
f=$(PREFIX)`basename $$p` ; \
rm -f $(DESTDIR)/bin/$$f ; \
fi \
done
endif
WARNING_BORDER =*******************************************************\n
NULL_ENTROPY_WARN_L1=**** WARNING! MBEDTLS_TEST_NULL_ENTROPY defined! ****\n
NULL_ENTROPY_WARN_L2=**** THIS BUILD HAS NO DEFINED ENTROPY SOURCES ****\n
NULL_ENTROPY_WARN_L3=**** AND IS *NOT* SUITABLE FOR PRODUCTION USE ****\n
NULL_ENTROPY_WARNING=\n$(WARNING_BORDER)$(NULL_ENTROPY_WARN_L1)$(NULL_ENTROPY_WARN_L2)$(NULL_ENTROPY_WARN_L3)$(WARNING_BORDER)
# Post build steps
post_build:
ifndef WINDOWS
# If NULL Entropy is configured, display an appropriate warning
-scripts/config.pl get MBEDTLS_TEST_NULL_ENTROPY && ([ $$? -eq 0 ]) && \
echo '$(NULL_ENTROPY_WARNING)'
endif
clean:
$(MAKE) -C library clean
$(MAKE) -C programs clean
$(MAKE) -C tests clean
ifndef WINDOWS
find . \( -name \*.gcno -o -name \*.gcda -o -name \*.info \) -exec rm {} +
endif
check: lib tests
$(MAKE) -C tests check
test: check
ifndef WINDOWS
# note: for coverage testing, build with:
# make CFLAGS='--coverage -g3 -O0'
covtest:
$(MAKE) check
programs/test/selftest
tests/compat.sh
tests/ssl-opt.sh
lcov:
rm -rf Coverage
lcov --capture --initial --directory library -o files.info
lcov --capture --directory library -o tests.info
lcov --add-tracefile files.info --add-tracefile tests.info -o all.info
lcov --remove all.info -o final.info '*.h'
gendesc tests/Descriptions.txt -o descriptions
genhtml --title "mbed TLS" --description-file descriptions --keep-descriptions --legend --no-branch-coverage -o Coverage final.info
rm -f files.info tests.info all.info final.info descriptions
apidoc:
mkdir -p apidoc
doxygen doxygen/mbedtls.doxyfile
apidoc_clean:
rm -rf apidoc
endif

View file

@ -0,0 +1,185 @@
README for mbed TLS
===================
Configuration
-------------
mbed TLS should build out of the box on most systems. Some platform specific options are available in the fully documented configuration file `include/mbedtls/config.h`, which is also the place where features can be selected. This file can be edited manually, or in a more programmatic way using the Perl script `scripts/config.pl` (use `--help` for usage instructions).
Compiler options can be set using conventional environment variables such as `CC` and `CFLAGS` when using the Make and CMake build system (see below).
Compiling
---------
There are currently four active build systems used within mbed TLS releases:
- yotta
- Make
- CMake
- Microsoft Visual Studio (Visual Studio 6 and Visual Studio 2010)
The main systems used for development are CMake and Make. Those systems are always complete and up-to-date. The others should reflect all changes present in the CMake and Make build system, although features may not be ported there automatically.
Yotta, as a build system, is slightly different from the other build systems:
- it provides a minimalistic configuration file by default
- depending on the yotta target, features of mbed OS may be used in examples and tests
The Make and CMake build systems create three libraries: libmbedcrypto, libmbedx509, and libmbedtls. Note that libmbedtls depends on libmbedx509 and libmbedcrypto, and libmbedx509 depends on libmbedcrypto. As a result, some linkers will expect flags to be in a specific order, for example the GNU linker wants `-lmbedtls -lmbedx509 -lmbedcrypto`. Also, when loading shared libraries using dlopen(), you'll need to load libmbedcrypto first, then libmbedx509, before you can load libmbedtls.
### Yotta
[yotta](http://yottabuild.org) is a package manager and build system developed by mbed, and is the build system of mbed OS 16.03. To install it on your platform, please follow the yotta [installation instructions](http://docs.yottabuild.org/#installing).
Once yotta is installed, you can use it to download the latest version of mbed TLS from the yotta registry with:
yotta install mbedtls
and build it with:
yotta build
If, on the other hand, you already have a copy of mbed TLS from a source other than the yotta registry, for example from cloning our GitHub repository, or from downloading a tarball of the standalone edition, then you'll first need to generate the yotta module by running:
yotta/create-module.sh
This should be executed from the root mbed TLS project directory. This will create the yotta module in the `yotta/module` directory within it. You can then change to that directory and build as usual:
cd yotta/module
yotta build
In any case, you'll probably want to set the yotta target before building unless it has already been set globally. For more information on using yotta, please consult the [yotta documentation](http://docs.yottabuild.org/).
For more details on the yotta/mbed OS edition of mbed TLS, including example programs, please consult the [Readme at the root of the yotta module](https://github.com/ARMmbed/mbedtls/blob/development/yotta/data/README.md).
### Make
We intentionally only use the minimum of `Make` functionality, as a lot of `Make` features are not supported on all different implementations of Make or on different platforms. As such, the Makefiles sometimes require some manual changes or export statements in order to work for your platform.
In order to build from the source code using Make, just enter at the command line:
make
In order to run the tests, enter:
make check
The tests need Perl to be built and run. If you don't have Perl installed, you can skip building the tests with:
make no_test
You'll still be able to run a much smaller set of tests with:
programs/test/selftest
In order to build for a Windows platform, you should use `WINDOWS_BUILD=1` if the target is Windows but the build environment is Unix-like (for instance when cross-compiling, or compiling from an MSYS shell), and `WINDOWS=1` if the build environment is a Windows shell (for instance using mingw32-make) (in that case some targets will not be available).
Setting the variable `SHARED` in your environment will build shared libraries in addition to the static libraries. Setting `DEBUG` gives you a debug build. You can override `CFLAGS` and `LDFLAGS` by setting them in your environment or on the make command line; if you do so, essential parts such as `-I` will still be preserved. Warning options may be overridden separately using `WARNING_CFLAGS`.
Depending on your platform, you might run into some issues. Please check the Makefiles in `library/`, `programs/` and `tests/` for options to manually add or remove for specific platforms. You can also check [the mbed TLS Knowledge Base](https://tls.mbed.org/kb) for articles on your platform or issue.
In case you find that you need to do something else as well, please let us know what, so we can add it to the [mbed TLS knowledge base](https://tls.mbed.org/kb).
### CMake
In order to build the source using CMake, just enter at the command line:
cmake .
make
In order to run the tests, enter:
make test
The test suites need Perl to be built. If you don't have Perl installed, you'll want to disable the test suites with:
cmake -DENABLE_TESTING=Off .
If you disabled the test suites, but kept the programs enabled, you can still run a much smaller set of tests with:
programs/test/selftest
To configure CMake for building shared libraries, use:
cmake -DUSE_SHARED_MBEDTLS_LIBRARY=On .
There are many different build modes available within the CMake buildsystem. Most of them are available for gcc and clang, though some are compiler-specific:
- Release. This generates the default code without any unnecessary information in the binary files.
- Debug. This generates debug information and disables optimization of the code.
- Coverage. This generates code coverage information in addition to debug information.
- ASan. This instruments the code with AddressSanitizer to check for memory errors. (This includes LeakSanitizer, with recent version of gcc and clang.) (With recent version of clang, this mode also instruments the code with UndefinedSanitizer to check for undefined behaviour.)
- ASanDbg. Same as ASan but slower, with debug information and better stack traces.
- MemSan. This instruments the code with MemorySanitizer to check for uninitialised memory reads. Experimental, needs recent clang on Linux/x86\_64.
- MemSanDbg. Same as MemSan but slower, with debug information, better stack traces and origin tracking.
- Check. This activates the compiler warnings that depend on optimization and treats all warnings as errors.
Switching build modes in CMake is simple. For debug mode, enter at the command line:
cmake -D CMAKE_BUILD_TYPE=Debug .
To list other available CMake options, use:
cmake -LH
Note that, with CMake, if you want to change the compiler or its options after you already ran CMake, you need to clear its cache first, e.g. (using GNU find):
find . -iname '*cmake*' -not -name CMakeLists.txt -exec rm -rf {} +
CC=gcc CFLAGS='-fstack-protector-strong -Wa,--noexecstack' cmake .
### Microsoft Visual Studio
The build files for Microsoft Visual Studio are generated for Visual Studio 2010.
The solution file `mbedTLS.sln` contains all the basic projects needed to build the library and all the programs. The files in tests are not generated and compiled, as these need a perl environment as well. However, the selftest program in `programs/test/` is still available.
Example programs
----------------
We've included example programs for a lot of different features and uses in `programs/`. Most programs only focus on a single feature or usage scenario, so keep that in mind when copying parts of the code.
Tests
-----
mbed TLS includes an elaborate test suite in `tests/` that initially requires Perl to generate the tests files (e.g. `test\_suite\_mpi.c`). These files are generated from a `function file` (e.g. `suites/test\_suite\_mpi.function`) and a `data file` (e.g. `suites/test\_suite\_mpi.data`). The `function file` contains the test functions. The `data file` contains the test cases, specified as parameters that will be passed to the test function.
For machines with a Unix shell and OpenSSL (and optionally GnuTLS) installed, additional test scripts are available:
- `tests/ssl-opt.sh` runs integration tests for various TLS options (renegotiation, resumption, etc.) and tests interoperability of these options with other implementations.
- `tests/compat.sh` tests interoperability of every ciphersuite with other implementations.
- `tests/scripts/test-ref-configs.pl` test builds in various reduced configurations.
- `tests/scripts/key-exchanges.pl` test builds in configurations with a single key exchange enabled
- `tests/scripts/all.sh` runs a combination of the above tests, plus some more, with various build options (such as ASan, full `config.h`, etc).
Configurations
--------------
We provide some non-standard configurations focused on specific use cases in the `configs/` directory. You can read more about those in `configs/README.txt`
Porting mbed TLS
----------------
mbed TLS can be ported to many different architectures, OS's and platforms. Before starting a port, you may find the following knowledge base articles useful:
- [Porting mbed TLS to a new environment or OS](https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS)
- [What external dependencies does mbed TLS rely on?](https://tls.mbed.org/kb/development/what-external-dependencies-does-mbedtls-rely-on)
- [How do I configure mbed TLS](https://tls.mbed.org/kb/compiling-and-building/how-do-i-configure-mbedtls)
Contributing
------------
We gratefully accept bug reports and contributions from the community. There are some requirements we need to fulfill in order to be able to integrate contributions:
- All contributions, whether large or small require a Contributor's License Agreement (CLA) to be accepted. This is because source code can possibly fall under copyright law and we need your consent to share in the ownership of the copyright.
- We would ask that contributions conform to [our coding standards](https://tls.mbed.org/kb/development/mbedtls-coding-standards), and that contributions should be fully tested before submission.
- As with any open source project, contributions will be reviewed by the project team and community and may need some modifications to be accepted.
To accept the Contributors Licence Agreement (CLA), individual contributors can do this by creating an mbed account and [accepting the online agreement here with a click through](https://developer.mbed.org/contributor_agreement/). Alternatively, for contributions from corporations, or those that do not wish to create an mbed account, a slightly different agreement can be found [here](https://www.mbed.com/en/about-mbed/contributor-license-agreements/). This agreement should be signed and returned to ARM as described in the instructions given.
### Making a Contribution
1. [Check for open issues](https://github.com/ARMmbed/mbedtls/issues) or [start a discussion](https://tls.mbed.org/discussions) around a feature idea or a bug.
2. Fork the [mbed TLS repository on GitHub](https://github.com/ARMmbed/mbedtls) to start making your changes. As a general rule, you should use the "development" branch as a basis.
3. Write a test which shows that the bug was fixed or that the feature works as expected.
4. Send a pull request and bug us until it gets merged and published. Contributions may need some modifications, so work with us to get your change accepted. We will include your name in the ChangeLog :)

View file

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View file

@ -0,0 +1,44 @@
# Purpose:
# - To test and prove that a new commit in the mbed TLS repository builds
# and integrates with mbed-os properly.
# AND
# - To test and prove that the current development head of mbed TLS builds
# and integrates with the current mbed-os master branch.
#
# The script fetches all the prerequisites and builds the mbed TLS 'tls-client'
# example. This script is triggered by every commit and once each night and the
# exact behaviour depends on how it was triggered:
# - If it is a nightly build then it builds the mbed TLS development head with
# mbed-os master.
# - If it was triggered by the commit, then it builds the example with mbed TLS
# at that commit and mbed-os at the commit pointed by mbed-os.lib in the
# example repository.
test:
override:
- cd ../mbed-os-example-tls/tls-client/ && mbed compile -m K64F -t GCC_ARM -c
dependencies:
pre:
# Install gcc-arm
- cd .. && wget "https://launchpad.net/gcc-arm-embedded/4.9/4.9-2015-q3-update/+download/gcc-arm-none-eabi-4_9-2015q3-20150921-linux.tar.bz2"
- cd .. && tar -xvjf gcc-arm-none-eabi-4_9-2015q3-20150921-linux.tar.bz2
- ln -s ../gcc-arm-none-eabi-4_9-2015q3/bin/* ../bin/
# Install mbed-cli
- cd ../ && git clone https://github.com/ARMmbed/mbed-cli.git
- cd ../mbed-cli && sudo -H pip install -e .
# Get the sample application
- cd ../ && git clone git@github.com:ARMmbed/mbed-os-example-tls.git
# Get mbed-os
- cd ../mbed-os-example-tls/tls-client && mbed deploy
# Update mbed-os to master only if it is a nightly build
- >
if [ -n "${RUN_NIGHTLY_BUILD}" ]; then
cd ../mbed-os-example-tls/tls-client/mbed-os/ && mbed update master;
fi
# Import mbedtls current revision
- ln -s ../../../../../../../mbedtls/ ../mbed-os-example-tls/tls-client/mbed-os/features/mbedtls/importer/TARGET_IGNORE/mbedtls
- cd ../mbed-os-example-tls/tls-client/mbed-os/features/mbedtls/importer/ && make
override:
# Install the missing python packages
- cd ../mbed-os-example-tls/tls-client/mbed-os/ && sudo -H pip install -r requirements.txt

View file

@ -0,0 +1,4 @@
Makefile
*.sln
*.vcxproj
mbedtls/check_config

View file

@ -0,0 +1,11 @@
option(INSTALL_MBEDTLS_HEADERS "Install mbed TLS headers." ON)
if(INSTALL_MBEDTLS_HEADERS)
file(GLOB headers "mbedtls/*.h")
install(FILES ${headers}
DESTINATION include/mbedtls
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
endif(INSTALL_MBEDTLS_HEADERS)

View file

@ -0,0 +1,297 @@
/**
* \file aes.h
*
* \brief AES block cipher
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_AES_H
#define MBEDTLS_AES_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include <stdint.h>
/* padlock.c and aesni.c rely on these values! */
#define MBEDTLS_AES_ENCRYPT 1
#define MBEDTLS_AES_DECRYPT 0
#define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */
#define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */
#if !defined(MBEDTLS_AES_ALT)
// Regular implementation
//
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief AES context structure
*
* \note buf is able to hold 32 extra bytes, which can be used:
* - for alignment purposes if VIA padlock is used, and/or
* - to simplify key expansion in the 256-bit case by
* generating an extra round key
*/
typedef struct
{
int nr; /*!< number of rounds */
uint32_t *rk; /*!< AES round keys */
uint32_t buf[68]; /*!< unaligned data */
}
mbedtls_aes_context;
/**
* \brief Initialize AES context
*
* \param ctx AES context to be initialized
*/
void mbedtls_aes_init( mbedtls_aes_context *ctx );
/**
* \brief Clear AES context
*
* \param ctx AES context to be cleared
*/
void mbedtls_aes_free( mbedtls_aes_context *ctx );
/**
* \brief AES key schedule (encryption)
*
* \param ctx AES context to be initialized
* \param key encryption key
* \param keybits must be 128, 192 or 256
*
* \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
*/
int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
unsigned int keybits );
/**
* \brief AES key schedule (decryption)
*
* \param ctx AES context to be initialized
* \param key decryption key
* \param keybits must be 128, 192 or 256
*
* \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
*/
int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
unsigned int keybits );
/**
* \brief AES-ECB block encryption/decryption
*
* \param ctx AES context
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
* \param input 16-byte input block
* \param output 16-byte output block
*
* \return 0 if successful
*/
int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16] );
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/**
* \brief AES-CBC buffer encryption/decryption
* Length should be a multiple of the block
* size (16 bytes)
*
* \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx AES context
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
*/
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 );
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_CIPHER_MODE_CFB)
/**
* \brief AES-CFB128 buffer encryption/decryption.
*
* Note: Due to the nature of CFB you should use the same key schedule for
* both encryption and decryption. So a context initialized with
* mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT.
*
* \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx AES context
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
* \param length length of the input data
* \param iv_off offset in IV (updated after use)
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful
*/
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 );
/**
* \brief AES-CFB8 buffer encryption/decryption.
*
* Note: Due to the nature of CFB you should use the same key schedule for
* both encryption and decryption. So a context initialized with
* mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT.
*
* \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx AES context
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful
*/
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 );
#endif /*MBEDTLS_CIPHER_MODE_CFB */
#if defined(MBEDTLS_CIPHER_MODE_CTR)
/**
* \brief AES-CTR buffer encryption/decryption
*
* Warning: You have to keep the maximum use of your counter in mind!
*
* Note: Due to the nature of CTR you should use the same key schedule for
* both encryption and decryption. So a context initialized with
* mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT.
*
* \param ctx AES context
* \param length The length of the data
* \param nc_off The offset in the current stream_block (for resuming
* within current cipher stream). The offset pointer to
* should be 0 at the start of a stream.
* \param nonce_counter The 128-bit nonce and counter.
* \param stream_block The saved stream-block for resuming. Is overwritten
* by the function.
* \param input The input data stream
* \param output The output data stream
*
* \return 0 if successful
*/
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 );
#endif /* MBEDTLS_CIPHER_MODE_CTR */
/**
* \brief Internal AES block encryption function
* (Only exposed to allow overriding it,
* see MBEDTLS_AES_ENCRYPT_ALT)
*
* \param ctx AES context
* \param input Plaintext block
* \param output Output (ciphertext) block
*/
void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
const unsigned char input[16],
unsigned char output[16] );
/**
* \brief Internal AES block decryption function
* (Only exposed to allow overriding it,
* see MBEDTLS_AES_DECRYPT_ALT)
*
* \param ctx AES context
* \param input Ciphertext block
* \param output Output (plaintext) block
*/
void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
const unsigned char input[16],
unsigned char output[16] );
#ifdef __cplusplus
}
#endif
#else /* MBEDTLS_AES_ALT */
#include "aes_alt.h"
#endif /* MBEDTLS_AES_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mbedtls_aes_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* aes.h */

View file

@ -0,0 +1,111 @@
/**
* \file aesni.h
*
* \brief AES-NI for hardware AES acceleration on some Intel processors
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_AESNI_H
#define MBEDTLS_AESNI_H
#include "aes.h"
#define MBEDTLS_AESNI_AES 0x02000000u
#define MBEDTLS_AESNI_CLMUL 0x00000002u
#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && \
( defined(__amd64__) || defined(__x86_64__) ) && \
! defined(MBEDTLS_HAVE_X86_64)
#define MBEDTLS_HAVE_X86_64
#endif
#if defined(MBEDTLS_HAVE_X86_64)
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief AES-NI features detection routine
*
* \param what The feature to detect
* (MBEDTLS_AESNI_AES or MBEDTLS_AESNI_CLMUL)
*
* \return 1 if CPU has support for the feature, 0 otherwise
*/
int mbedtls_aesni_has_support( unsigned int what );
/**
* \brief AES-NI AES-ECB block en(de)cryption
*
* \param ctx AES context
* \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
* \param input 16-byte input block
* \param output 16-byte output block
*
* \return 0 on success (cannot fail)
*/
int mbedtls_aesni_crypt_ecb( mbedtls_aes_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16] );
/**
* \brief GCM multiplication: c = a * b in GF(2^128)
*
* \param c Result
* \param a First operand
* \param b Second operand
*
* \note Both operands and result are bit strings interpreted as
* elements of GF(2^128) as per the GCM spec.
*/
void mbedtls_aesni_gcm_mult( unsigned char c[16],
const unsigned char a[16],
const unsigned char b[16] );
/**
* \brief Compute decryption round keys from encryption round keys
*
* \param invkey Round keys for the equivalent inverse cipher
* \param fwdkey Original round keys (for encryption)
* \param nr Number of rounds (that is, number of round keys minus one)
*/
void mbedtls_aesni_inverse_key( unsigned char *invkey,
const unsigned char *fwdkey, int nr );
/**
* \brief Perform key expansion (for encryption)
*
* \param rk Destination buffer where the round keys are written
* \param key Encryption key
* \param bits Key size in bits (must be 128, 192 or 256)
*
* \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
*/
int mbedtls_aesni_setkey_enc( unsigned char *rk,
const unsigned char *key,
size_t bits );
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_HAVE_X86_64 */
#endif /* MBEDTLS_AESNI_H */

View file

@ -0,0 +1,113 @@
/**
* \file arc4.h
*
* \brief The ARCFOUR stream cipher
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_ARC4_H
#define MBEDTLS_ARC4_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#if !defined(MBEDTLS_ARC4_ALT)
// Regular implementation
//
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief ARC4 context structure
*/
typedef struct
{
int x; /*!< permutation index */
int y; /*!< permutation index */
unsigned char m[256]; /*!< permutation table */
}
mbedtls_arc4_context;
/**
* \brief Initialize ARC4 context
*
* \param ctx ARC4 context to be initialized
*/
void mbedtls_arc4_init( mbedtls_arc4_context *ctx );
/**
* \brief Clear ARC4 context
*
* \param ctx ARC4 context to be cleared
*/
void mbedtls_arc4_free( mbedtls_arc4_context *ctx );
/**
* \brief ARC4 key schedule
*
* \param ctx ARC4 context to be setup
* \param key the secret key
* \param keylen length of the key, in bytes
*/
void mbedtls_arc4_setup( mbedtls_arc4_context *ctx, const unsigned char *key,
unsigned int keylen );
/**
* \brief ARC4 cipher function
*
* \param ctx ARC4 context
* \param length length of the input data
* \param input buffer holding the input data
* \param output buffer for the output data
*
* \return 0 if successful
*/
int mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned char *input,
unsigned char *output );
#ifdef __cplusplus
}
#endif
#else /* MBEDTLS_ARC4_ALT */
#include "arc4_alt.h"
#endif /* MBEDTLS_ARC4_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mbedtls_arc4_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* arc4.h */

View file

@ -0,0 +1,342 @@
/**
* \file asn1.h
*
* \brief Generic ASN.1 parsing
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_ASN1_H
#define MBEDTLS_ASN1_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#if defined(MBEDTLS_BIGNUM_C)
#include "bignum.h"
#endif
/**
* \addtogroup asn1_module
* \{
*/
/**
* \name ASN1 Error codes
* These error codes are OR'ed to X509 error codes for
* higher error granularity.
* ASN1 is a standard to specify data structures.
* \{
*/
#define MBEDTLS_ERR_ASN1_OUT_OF_DATA -0x0060 /**< Out of data when parsing an ASN1 data structure. */
#define MBEDTLS_ERR_ASN1_UNEXPECTED_TAG -0x0062 /**< ASN1 tag was of an unexpected value. */
#define MBEDTLS_ERR_ASN1_INVALID_LENGTH -0x0064 /**< Error when trying to determine the length or invalid length. */
#define MBEDTLS_ERR_ASN1_LENGTH_MISMATCH -0x0066 /**< Actual length differs from expected length. */
#define MBEDTLS_ERR_ASN1_INVALID_DATA -0x0068 /**< Data is invalid. (not used) */
#define MBEDTLS_ERR_ASN1_ALLOC_FAILED -0x006A /**< Memory allocation failed */
#define MBEDTLS_ERR_ASN1_BUF_TOO_SMALL -0x006C /**< Buffer too small when writing ASN.1 data structure. */
/* \} name */
/**
* \name DER constants
* These constants comply with DER encoded the ANS1 type tags.
* DER encoding uses hexadecimal representation.
* An example DER sequence is:\n
* - 0x02 -- tag indicating INTEGER
* - 0x01 -- length in octets
* - 0x05 -- value
* Such sequences are typically read into \c ::mbedtls_x509_buf.
* \{
*/
#define MBEDTLS_ASN1_BOOLEAN 0x01
#define MBEDTLS_ASN1_INTEGER 0x02
#define MBEDTLS_ASN1_BIT_STRING 0x03
#define MBEDTLS_ASN1_OCTET_STRING 0x04
#define MBEDTLS_ASN1_NULL 0x05
#define MBEDTLS_ASN1_OID 0x06
#define MBEDTLS_ASN1_UTF8_STRING 0x0C
#define MBEDTLS_ASN1_SEQUENCE 0x10
#define MBEDTLS_ASN1_SET 0x11
#define MBEDTLS_ASN1_PRINTABLE_STRING 0x13
#define MBEDTLS_ASN1_T61_STRING 0x14
#define MBEDTLS_ASN1_IA5_STRING 0x16
#define MBEDTLS_ASN1_UTC_TIME 0x17
#define MBEDTLS_ASN1_GENERALIZED_TIME 0x18
#define MBEDTLS_ASN1_UNIVERSAL_STRING 0x1C
#define MBEDTLS_ASN1_BMP_STRING 0x1E
#define MBEDTLS_ASN1_PRIMITIVE 0x00
#define MBEDTLS_ASN1_CONSTRUCTED 0x20
#define MBEDTLS_ASN1_CONTEXT_SPECIFIC 0x80
/* \} name */
/* \} addtogroup asn1_module */
/** Returns the size of the binary string, without the trailing \\0 */
#define MBEDTLS_OID_SIZE(x) (sizeof(x) - 1)
/**
* Compares an mbedtls_asn1_buf structure to a reference OID.
*
* Only works for 'defined' oid_str values (MBEDTLS_OID_HMAC_SHA1), you cannot use a
* 'unsigned char *oid' here!
*/
#define MBEDTLS_OID_CMP(oid_str, oid_buf) \
( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf)->len ) || \
memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) != 0 )
#ifdef __cplusplus
extern "C" {
#endif
/**
* \name Functions to parse ASN.1 data structures
* \{
*/
/**
* Type-length-value structure that allows for ASN1 using DER.
*/
typedef struct mbedtls_asn1_buf
{
int tag; /**< ASN1 type, e.g. MBEDTLS_ASN1_UTF8_STRING. */
size_t len; /**< ASN1 length, in octets. */
unsigned char *p; /**< ASN1 data, e.g. in ASCII. */
}
mbedtls_asn1_buf;
/**
* Container for ASN1 bit strings.
*/
typedef struct mbedtls_asn1_bitstring
{
size_t len; /**< ASN1 length, in octets. */
unsigned char unused_bits; /**< Number of unused bits at the end of the string */
unsigned char *p; /**< Raw ASN1 data for the bit string */
}
mbedtls_asn1_bitstring;
/**
* Container for a sequence of ASN.1 items
*/
typedef struct mbedtls_asn1_sequence
{
mbedtls_asn1_buf buf; /**< Buffer containing the given ASN.1 item. */
struct mbedtls_asn1_sequence *next; /**< The next entry in the sequence. */
}
mbedtls_asn1_sequence;
/**
* Container for a sequence or list of 'named' ASN.1 data items
*/
typedef struct mbedtls_asn1_named_data
{
mbedtls_asn1_buf oid; /**< The object identifier. */
mbedtls_asn1_buf val; /**< The named value. */
struct mbedtls_asn1_named_data *next; /**< The next entry in the sequence. */
unsigned char next_merged; /**< Merge next item into the current one? */
}
mbedtls_asn1_named_data;
/**
* \brief Get the length of an ASN.1 element.
* Updates the pointer to immediately behind the length.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param len The variable that will receive the value
*
* \return 0 if successful, MBEDTLS_ERR_ASN1_OUT_OF_DATA on reaching
* end of data, MBEDTLS_ERR_ASN1_INVALID_LENGTH if length is
* unparseable.
*/
int mbedtls_asn1_get_len( unsigned char **p,
const unsigned char *end,
size_t *len );
/**
* \brief Get the tag and length of the tag. Check for the requested tag.
* Updates the pointer to immediately behind the tag and length.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param len The variable that will receive the length
* \param tag The expected tag
*
* \return 0 if successful, MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if tag did
* not match requested tag, or another specific ASN.1 error code.
*/
int mbedtls_asn1_get_tag( unsigned char **p,
const unsigned char *end,
size_t *len, int tag );
/**
* \brief Retrieve a boolean ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param val The variable that will receive the value
*
* \return 0 if successful or a specific ASN.1 error code.
*/
int mbedtls_asn1_get_bool( unsigned char **p,
const unsigned char *end,
int *val );
/**
* \brief Retrieve an integer ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param val The variable that will receive the value
*
* \return 0 if successful or a specific ASN.1 error code.
*/
int mbedtls_asn1_get_int( unsigned char **p,
const unsigned char *end,
int *val );
/**
* \brief Retrieve a bitstring ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param bs The variable that will receive the value
*
* \return 0 if successful or a specific ASN.1 error code.
*/
int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end,
mbedtls_asn1_bitstring *bs);
/**
* \brief Retrieve a bitstring ASN.1 tag without unused bits and its
* value.
* Updates the pointer to the beginning of the bit/octet string.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param len Length of the actual bit/octect string in bytes
*
* \return 0 if successful or a specific ASN.1 error code.
*/
int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
size_t *len );
/**
* \brief Parses and splits an ASN.1 "SEQUENCE OF <tag>"
* Updated the pointer to immediately behind the full sequence tag.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param cur First variable in the chain to fill
* \param tag Type of sequence
*
* \return 0 if successful or a specific ASN.1 error code.
*/
int mbedtls_asn1_get_sequence_of( unsigned char **p,
const unsigned char *end,
mbedtls_asn1_sequence *cur,
int tag);
#if defined(MBEDTLS_BIGNUM_C)
/**
* \brief Retrieve a MPI value from an integer ASN.1 tag.
* Updates the pointer to immediately behind the full tag.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param X The MPI that will receive the value
*
* \return 0 if successful or a specific ASN.1 or MPI error code.
*/
int mbedtls_asn1_get_mpi( unsigned char **p,
const unsigned char *end,
mbedtls_mpi *X );
#endif /* MBEDTLS_BIGNUM_C */
/**
* \brief Retrieve an AlgorithmIdentifier ASN.1 sequence.
* Updates the pointer to immediately behind the full
* AlgorithmIdentifier.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param alg The buffer to receive the OID
* \param params The buffer to receive the params (if any)
*
* \return 0 if successful or a specific ASN.1 or MPI error code.
*/
int mbedtls_asn1_get_alg( unsigned char **p,
const unsigned char *end,
mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params );
/**
* \brief Retrieve an AlgorithmIdentifier ASN.1 sequence with NULL or no
* params.
* Updates the pointer to immediately behind the full
* AlgorithmIdentifier.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param alg The buffer to receive the OID
*
* \return 0 if successful or a specific ASN.1 or MPI error code.
*/
int mbedtls_asn1_get_alg_null( unsigned char **p,
const unsigned char *end,
mbedtls_asn1_buf *alg );
/**
* \brief Find a specific named_data entry in a sequence or list based on
* the OID.
*
* \param list The list to seek through
* \param oid The OID to look for
* \param len Size of the OID
*
* \return NULL if not found, or a pointer to the existing entry.
*/
mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *list,
const char *oid, size_t len );
/**
* \brief Free a mbedtls_asn1_named_data entry
*
* \param entry The named data entry to free
*/
void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *entry );
/**
* \brief Free all entries in a mbedtls_asn1_named_data list
* Head will be set to NULL
*
* \param head Pointer to the head of the list of named data entries to free
*/
void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head );
#ifdef __cplusplus
}
#endif
#endif /* asn1.h */

View file

@ -0,0 +1,239 @@
/**
* \file asn1write.h
*
* \brief ASN.1 buffer writing functionality
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_ASN1_WRITE_H
#define MBEDTLS_ASN1_WRITE_H
#include "asn1.h"
#define MBEDTLS_ASN1_CHK_ADD(g, f) do { if( ( ret = f ) < 0 ) return( ret ); else \
g += ret; } while( 0 )
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Write a length field in ASN.1 format
* Note: function works backwards in data buffer
*
* \param p reference to current position pointer
* \param start start of the buffer (for bounds-checking)
* \param len the length to write
*
* \return the length written or a negative error code
*/
int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len );
/**
* \brief Write a ASN.1 tag in ASN.1 format
* Note: function works backwards in data buffer
*
* \param p reference to current position pointer
* \param start start of the buffer (for bounds-checking)
* \param tag the tag to write
*
* \return the length written or a negative error code
*/
int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start,
unsigned char tag );
/**
* \brief Write raw buffer data
* Note: function works backwards in data buffer
*
* \param p reference to current position pointer
* \param start start of the buffer (for bounds-checking)
* \param buf data buffer to write
* \param size length of the data buffer
*
* \return the length written or a negative error code
*/
int mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start,
const unsigned char *buf, size_t size );
#if defined(MBEDTLS_BIGNUM_C)
/**
* \brief Write a big number (MBEDTLS_ASN1_INTEGER) in ASN.1 format
* Note: function works backwards in data buffer
*
* \param p reference to current position pointer
* \param start start of the buffer (for bounds-checking)
* \param X the MPI to write
*
* \return the length written or a negative error code
*/
int mbedtls_asn1_write_mpi( unsigned char **p, unsigned char *start, const mbedtls_mpi *X );
#endif /* MBEDTLS_BIGNUM_C */
/**
* \brief Write a NULL tag (MBEDTLS_ASN1_NULL) with zero data in ASN.1 format
* Note: function works backwards in data buffer
*
* \param p reference to current position pointer
* \param start start of the buffer (for bounds-checking)
*
* \return the length written or a negative error code
*/
int mbedtls_asn1_write_null( unsigned char **p, unsigned char *start );
/**
* \brief Write an OID tag (MBEDTLS_ASN1_OID) and data in ASN.1 format
* Note: function works backwards in data buffer
*
* \param p reference to current position pointer
* \param start start of the buffer (for bounds-checking)
* \param oid the OID to write
* \param oid_len length of the OID
*
* \return the length written or a negative error code
*/
int mbedtls_asn1_write_oid( unsigned char **p, unsigned char *start,
const char *oid, size_t oid_len );
/**
* \brief Write an AlgorithmIdentifier sequence in ASN.1 format
* Note: function works backwards in data buffer
*
* \param p reference to current position pointer
* \param start start of the buffer (for bounds-checking)
* \param oid the OID of the algorithm
* \param oid_len length of the OID
* \param par_len length of parameters, which must be already written.
* If 0, NULL parameters are added
*
* \return the length written or a negative error code
*/
int mbedtls_asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start,
const char *oid, size_t oid_len,
size_t par_len );
/**
* \brief Write a boolean tag (MBEDTLS_ASN1_BOOLEAN) and value in ASN.1 format
* Note: function works backwards in data buffer
*
* \param p reference to current position pointer
* \param start start of the buffer (for bounds-checking)
* \param boolean 0 or 1
*
* \return the length written or a negative error code
*/
int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start, int boolean );
/**
* \brief Write an int tag (MBEDTLS_ASN1_INTEGER) and value in ASN.1 format
* Note: function works backwards in data buffer
*
* \param p reference to current position pointer
* \param start start of the buffer (for bounds-checking)
* \param val the integer value
*
* \return the length written or a negative error code
*/
int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val );
/**
* \brief Write a printable string tag (MBEDTLS_ASN1_PRINTABLE_STRING) and
* value in ASN.1 format
* Note: function works backwards in data buffer
*
* \param p reference to current position pointer
* \param start start of the buffer (for bounds-checking)
* \param text the text to write
* \param text_len length of the text
*
* \return the length written or a negative error code
*/
int mbedtls_asn1_write_printable_string( unsigned char **p, unsigned char *start,
const char *text, size_t text_len );
/**
* \brief Write an IA5 string tag (MBEDTLS_ASN1_IA5_STRING) and
* value in ASN.1 format
* Note: function works backwards in data buffer
*
* \param p reference to current position pointer
* \param start start of the buffer (for bounds-checking)
* \param text the text to write
* \param text_len length of the text
*
* \return the length written or a negative error code
*/
int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start,
const char *text, size_t text_len );
/**
* \brief Write a bitstring tag (MBEDTLS_ASN1_BIT_STRING) and
* value in ASN.1 format
* Note: function works backwards in data buffer
*
* \param p reference to current position pointer
* \param start start of the buffer (for bounds-checking)
* \param buf the bitstring
* \param bits the total number of bits in the bitstring
*
* \return the length written or a negative error code
*/
int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start,
const unsigned char *buf, size_t bits );
/**
* \brief Write an octet string tag (MBEDTLS_ASN1_OCTET_STRING) and
* value in ASN.1 format
* Note: function works backwards in data buffer
*
* \param p reference to current position pointer
* \param start start of the buffer (for bounds-checking)
* \param buf data buffer to write
* \param size length of the data buffer
*
* \return the length written or a negative error code
*/
int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start,
const unsigned char *buf, size_t size );
/**
* \brief Create or find a specific named_data entry for writing in a
* sequence or list based on the OID. If not already in there,
* a new entry is added to the head of the list.
* Warning: Destructive behaviour for the val data!
*
* \param list Pointer to the location of the head of the list to seek
* through (will be updated in case of a new entry)
* \param oid The OID to look for
* \param oid_len Size of the OID
* \param val Data to store (can be NULL if you want to fill it by hand)
* \param val_len Minimum length of the data buffer needed
*
* \return NULL if if there was a memory allocation error, or a pointer
* to the new / existing entry.
*/
mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( mbedtls_asn1_named_data **list,
const char *oid, size_t oid_len,
const unsigned char *val,
size_t val_len );
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_ASN1_WRITE_H */

View file

@ -0,0 +1,88 @@
/**
* \file base64.h
*
* \brief RFC 1521 base64 encoding/decoding
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_BASE64_H
#define MBEDTLS_BASE64_H
#include <stddef.h>
#define MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL -0x002A /**< Output buffer too small. */
#define MBEDTLS_ERR_BASE64_INVALID_CHARACTER -0x002C /**< Invalid character in input. */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Encode a buffer into base64 format
*
* \param dst destination buffer
* \param dlen size of the destination buffer
* \param olen number of bytes written
* \param src source buffer
* \param slen amount of data to be encoded
*
* \return 0 if successful, or MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL.
* *olen is always updated to reflect the amount
* of data that has (or would have) been written.
* If that length cannot be represented, then no data is
* written to the buffer and *olen is set to the maximum
* length representable as a size_t.
*
* \note Call this function with dlen = 0 to obtain the
* required buffer size in *olen
*/
int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
const unsigned char *src, size_t slen );
/**
* \brief Decode a base64-formatted buffer
*
* \param dst destination buffer (can be NULL for checking size)
* \param dlen size of the destination buffer
* \param olen number of bytes written
* \param src source buffer
* \param slen amount of data to be decoded
*
* \return 0 if successful, MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL, or
* MBEDTLS_ERR_BASE64_INVALID_CHARACTER if the input data is
* not correct. *olen is always updated to reflect the amount
* of data that has (or would have) been written.
*
* \note Call this function with *dst = NULL or dlen = 0 to obtain
* the required buffer size in *olen
*/
int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
const unsigned char *src, size_t slen );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mbedtls_base64_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* base64.h */

View file

@ -0,0 +1,717 @@
/**
* \file bignum.h
*
* \brief Multi-precision integer library
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_BIGNUM_H
#define MBEDTLS_BIGNUM_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include <stdint.h>
#if defined(MBEDTLS_FS_IO)
#include <stdio.h>
#endif
#define MBEDTLS_ERR_MPI_FILE_IO_ERROR -0x0002 /**< An error occurred while reading from or writing to a file. */
#define MBEDTLS_ERR_MPI_BAD_INPUT_DATA -0x0004 /**< Bad input parameters to function. */
#define MBEDTLS_ERR_MPI_INVALID_CHARACTER -0x0006 /**< There is an invalid character in the digit string. */
#define MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL -0x0008 /**< The buffer is too small to write to. */
#define MBEDTLS_ERR_MPI_NEGATIVE_VALUE -0x000A /**< The input arguments are negative or result in illegal output. */
#define MBEDTLS_ERR_MPI_DIVISION_BY_ZERO -0x000C /**< The input argument for division is zero, which is not allowed. */
#define MBEDTLS_ERR_MPI_NOT_ACCEPTABLE -0x000E /**< The input arguments are not acceptable. */
#define MBEDTLS_ERR_MPI_ALLOC_FAILED -0x0010 /**< Memory allocation failed. */
#define MBEDTLS_MPI_CHK(f) do { if( ( ret = f ) != 0 ) goto cleanup; } while( 0 )
/*
* Maximum size MPIs are allowed to grow to in number of limbs.
*/
#define MBEDTLS_MPI_MAX_LIMBS 10000
#if !defined(MBEDTLS_MPI_WINDOW_SIZE)
/*
* Maximum window size used for modular exponentiation. Default: 6
* Minimum value: 1. Maximum value: 6.
*
* Result is an array of ( 2 << MBEDTLS_MPI_WINDOW_SIZE ) MPIs used
* for the sliding window calculation. (So 64 by default)
*
* Reduction in size, reduces speed.
*/
#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */
#endif /* !MBEDTLS_MPI_WINDOW_SIZE */
#if !defined(MBEDTLS_MPI_MAX_SIZE)
/*
* Maximum size of MPIs allowed in bits and bytes for user-MPIs.
* ( Default: 512 bytes => 4096 bits, Maximum tested: 2048 bytes => 16384 bits )
*
* Note: Calculations can results temporarily in larger MPIs. So the number
* of limbs required (MBEDTLS_MPI_MAX_LIMBS) is higher.
*/
#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */
#endif /* !MBEDTLS_MPI_MAX_SIZE */
#define MBEDTLS_MPI_MAX_BITS ( 8 * MBEDTLS_MPI_MAX_SIZE ) /**< Maximum number of bits for usable MPIs. */
/*
* When reading from files with mbedtls_mpi_read_file() and writing to files with
* mbedtls_mpi_write_file() the buffer should have space
* for a (short) label, the MPI (in the provided radix), the newline
* characters and the '\0'.
*
* By default we assume at least a 10 char label, a minimum radix of 10
* (decimal) and a maximum of 4096 bit numbers (1234 decimal chars).
* Autosized at compile time for at least a 10 char label, a minimum radix
* of 10 (decimal) for a number of MBEDTLS_MPI_MAX_BITS size.
*
* This used to be statically sized to 1250 for a maximum of 4096 bit
* numbers (1234 decimal chars).
*
* Calculate using the formula:
* MBEDTLS_MPI_RW_BUFFER_SIZE = ceil(MBEDTLS_MPI_MAX_BITS / ln(10) * ln(2)) +
* LabelSize + 6
*/
#define MBEDTLS_MPI_MAX_BITS_SCALE100 ( 100 * MBEDTLS_MPI_MAX_BITS )
#define MBEDTLS_LN_2_DIV_LN_10_SCALE100 332
#define MBEDTLS_MPI_RW_BUFFER_SIZE ( ((MBEDTLS_MPI_MAX_BITS_SCALE100 + MBEDTLS_LN_2_DIV_LN_10_SCALE100 - 1) / MBEDTLS_LN_2_DIV_LN_10_SCALE100) + 10 + 6 )
/*
* Define the base integer type, architecture-wise.
*
* 32-bit integers can be forced on 64-bit arches (eg. for testing purposes)
* by defining MBEDTLS_HAVE_INT32 and undefining MBEDTLS_HAVE_ASM
*/
#if ( ! defined(MBEDTLS_HAVE_INT32) && \
defined(_MSC_VER) && defined(_M_AMD64) )
#define MBEDTLS_HAVE_INT64
typedef int64_t mbedtls_mpi_sint;
typedef uint64_t mbedtls_mpi_uint;
#else
#if ( ! defined(MBEDTLS_HAVE_INT32) && \
defined(__GNUC__) && ( \
defined(__amd64__) || defined(__x86_64__) || \
defined(__ppc64__) || defined(__powerpc64__) || \
defined(__ia64__) || defined(__alpha__) || \
(defined(__sparc__) && defined(__arch64__)) || \
defined(__s390x__) || defined(__mips64) ) )
#define MBEDTLS_HAVE_INT64
typedef int64_t mbedtls_mpi_sint;
typedef uint64_t mbedtls_mpi_uint;
/* mbedtls_t_udbl defined as 128-bit unsigned int */
typedef unsigned int mbedtls_t_udbl __attribute__((mode(TI)));
#define MBEDTLS_HAVE_UDBL
#else
#define MBEDTLS_HAVE_INT32
typedef int32_t mbedtls_mpi_sint;
typedef uint32_t mbedtls_mpi_uint;
typedef uint64_t mbedtls_t_udbl;
#define MBEDTLS_HAVE_UDBL
#endif /* !MBEDTLS_HAVE_INT32 && __GNUC__ && 64-bit platform */
#endif /* !MBEDTLS_HAVE_INT32 && _MSC_VER && _M_AMD64 */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief MPI structure
*/
typedef struct
{
int s; /*!< integer sign */
size_t n; /*!< total # of limbs */
mbedtls_mpi_uint *p; /*!< pointer to limbs */
}
mbedtls_mpi;
/**
* \brief Initialize one MPI (make internal references valid)
* This just makes it ready to be set or freed,
* but does not define a value for the MPI.
*
* \param X One MPI to initialize.
*/
void mbedtls_mpi_init( mbedtls_mpi *X );
/**
* \brief Unallocate one MPI
*
* \param X One MPI to unallocate.
*/
void mbedtls_mpi_free( mbedtls_mpi *X );
/**
* \brief Enlarge to the specified number of limbs
*
* \param X MPI to grow
* \param nblimbs The target number of limbs
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs );
/**
* \brief Resize down, keeping at least the specified number of limbs
*
* \param X MPI to shrink
* \param nblimbs The minimum number of limbs to keep
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs );
/**
* \brief Copy the contents of Y into X
*
* \param X Destination MPI
* \param Y Source MPI
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y );
/**
* \brief Swap the contents of X and Y
*
* \param X First MPI value
* \param Y Second MPI value
*/
void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y );
/**
* \brief Safe conditional assignement X = Y if assign is 1
*
* \param X MPI to conditionally assign to
* \param Y Value to be assigned
* \param assign 1: perform the assignment, 0: keep X's original value
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
*
* \note This function is equivalent to
* if( assign ) mbedtls_mpi_copy( X, Y );
* except that it avoids leaking any information about whether
* the assignment was done or not (the above code may leak
* information through branch prediction and/or memory access
* patterns analysis).
*/
int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign );
/**
* \brief Safe conditional swap X <-> Y if swap is 1
*
* \param X First mbedtls_mpi value
* \param Y Second mbedtls_mpi value
* \param assign 1: perform the swap, 0: keep X and Y's original values
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
*
* \note This function is equivalent to
* if( assign ) mbedtls_mpi_swap( X, Y );
* except that it avoids leaking any information about whether
* the assignment was done or not (the above code may leak
* information through branch prediction and/or memory access
* patterns analysis).
*/
int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char assign );
/**
* \brief Set value from integer
*
* \param X MPI to set
* \param z Value to use
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z );
/**
* \brief Get a specific bit from X
*
* \param X MPI to use
* \param pos Zero-based index of the bit in X
*
* \return Either a 0 or a 1
*/
int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos );
/**
* \brief Set a bit of X to a specific value of 0 or 1
*
* \note Will grow X if necessary to set a bit to 1 in a not yet
* existing limb. Will not grow if bit should be set to 0
*
* \param X MPI to use
* \param pos Zero-based index of the bit in X
* \param val The value to set the bit to (0 or 1)
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
* MBEDTLS_ERR_MPI_BAD_INPUT_DATA if val is not 0 or 1
*/
int mbedtls_mpi_set_bit( mbedtls_mpi *X, size_t pos, unsigned char val );
/**
* \brief Return the number of zero-bits before the least significant
* '1' bit
*
* Note: Thus also the zero-based index of the least significant '1' bit
*
* \param X MPI to use
*/
size_t mbedtls_mpi_lsb( const mbedtls_mpi *X );
/**
* \brief Return the number of bits up to and including the most
* significant '1' bit'
*
* Note: Thus also the one-based index of the most significant '1' bit
*
* \param X MPI to use
*/
size_t mbedtls_mpi_bitlen( const mbedtls_mpi *X );
/**
* \brief Return the total size in bytes
*
* \param X MPI to use
*/
size_t mbedtls_mpi_size( const mbedtls_mpi *X );
/**
* \brief Import from an ASCII string
*
* \param X Destination MPI
* \param radix Input numeric base
* \param s Null-terminated string buffer
*
* \return 0 if successful, or a MBEDTLS_ERR_MPI_XXX error code
*/
int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s );
/**
* \brief Export into an ASCII string
*
* \param X Source MPI
* \param radix Output numeric base
* \param buf Buffer to write the string to
* \param buflen Length of buf
* \param olen Length of the string written, including final NUL byte
*
* \return 0 if successful, or a MBEDTLS_ERR_MPI_XXX error code.
* *olen is always updated to reflect the amount
* of data that has (or would have) been written.
*
* \note Call this function with buflen = 0 to obtain the
* minimum required buffer size in *olen.
*/
int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix,
char *buf, size_t buflen, size_t *olen );
#if defined(MBEDTLS_FS_IO)
/**
* \brief Read X from an opened file
*
* \param X Destination MPI
* \param radix Input numeric base
* \param fin Input file handle
*
* \return 0 if successful, MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if
* the file read buffer is too small or a
* MBEDTLS_ERR_MPI_XXX error code
*/
int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin );
/**
* \brief Write X into an opened file, or stdout if fout is NULL
*
* \param p Prefix, can be NULL
* \param X Source MPI
* \param radix Output numeric base
* \param fout Output file handle (can be NULL)
*
* \return 0 if successful, or a MBEDTLS_ERR_MPI_XXX error code
*
* \note Set fout == NULL to print X on the console.
*/
int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X, int radix, FILE *fout );
#endif /* MBEDTLS_FS_IO */
/**
* \brief Import X from unsigned binary data, big endian
*
* \param X Destination MPI
* \param buf Input buffer
* \param buflen Input buffer size
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen );
/**
* \brief Export X into unsigned binary data, big endian.
* Always fills the whole buffer, which will start with zeros
* if the number is smaller.
*
* \param X Source MPI
* \param buf Output buffer
* \param buflen Output buffer size
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough
*/
int mbedtls_mpi_write_binary( const mbedtls_mpi *X, unsigned char *buf, size_t buflen );
/**
* \brief Left-shift: X <<= count
*
* \param X MPI to shift
* \param count Amount to shift
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_shift_l( mbedtls_mpi *X, size_t count );
/**
* \brief Right-shift: X >>= count
*
* \param X MPI to shift
* \param count Amount to shift
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count );
/**
* \brief Compare unsigned values
*
* \param X Left-hand MPI
* \param Y Right-hand MPI
*
* \return 1 if |X| is greater than |Y|,
* -1 if |X| is lesser than |Y| or
* 0 if |X| is equal to |Y|
*/
int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y );
/**
* \brief Compare signed values
*
* \param X Left-hand MPI
* \param Y Right-hand MPI
*
* \return 1 if X is greater than Y,
* -1 if X is lesser than Y or
* 0 if X is equal to Y
*/
int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y );
/**
* \brief Compare signed values
*
* \param X Left-hand MPI
* \param z The integer value to compare to
*
* \return 1 if X is greater than z,
* -1 if X is lesser than z or
* 0 if X is equal to z
*/
int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z );
/**
* \brief Unsigned addition: X = |A| + |B|
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B );
/**
* \brief Unsigned subtraction: X = |A| - |B|
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_NEGATIVE_VALUE if B is greater than A
*/
int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B );
/**
* \brief Signed addition: X = A + B
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B );
/**
* \brief Signed subtraction: X = A - B
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B );
/**
* \brief Signed addition: X = A + b
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param b The integer value to add
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b );
/**
* \brief Signed subtraction: X = A - b
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param b The integer value to subtract
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b );
/**
* \brief Baseline multiplication: X = A * B
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B );
/**
* \brief Baseline multiplication: X = A * b
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param b The unsigned integer value to multiply with
*
* \note b is unsigned
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b );
/**
* \brief Division by mbedtls_mpi: A = Q * B + R
*
* \param Q Destination MPI for the quotient
* \param R Destination MPI for the rest value
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
* MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if B == 0
*
* \note Either Q or R can be NULL.
*/
int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B );
/**
* \brief Division by int: A = Q * b + R
*
* \param Q Destination MPI for the quotient
* \param R Destination MPI for the rest value
* \param A Left-hand MPI
* \param b Integer to divide by
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
* MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if b == 0
*
* \note Either Q or R can be NULL.
*/
int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, mbedtls_mpi_sint b );
/**
* \brief Modulo: R = A mod B
*
* \param R Destination MPI for the rest value
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
* MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if B == 0,
* MBEDTLS_ERR_MPI_NEGATIVE_VALUE if B < 0
*/
int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B );
/**
* \brief Modulo: r = A mod b
*
* \param r Destination mbedtls_mpi_uint
* \param A Left-hand MPI
* \param b Integer to divide by
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
* MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if b == 0,
* MBEDTLS_ERR_MPI_NEGATIVE_VALUE if b < 0
*/
int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_sint b );
/**
* \brief Sliding-window exponentiation: X = A^E mod N
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param E Exponent MPI
* \param N Modular MPI
* \param _RR Speed-up MPI used for recalculations
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
* MBEDTLS_ERR_MPI_BAD_INPUT_DATA if N is negative or even or
* if E is negative
*
* \note _RR is used to avoid re-computing R*R mod N across
* multiple calls, which speeds up things a bit. It can
* be set to NULL if the extra performance is unneeded.
*/
int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *E, const mbedtls_mpi *N, mbedtls_mpi *_RR );
/**
* \brief Fill an MPI X with size bytes of random
*
* \param X Destination MPI
* \param size Size in bytes
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Greatest common divisor: G = gcd(A, B)
*
* \param G Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B );
/**
* \brief Modular inverse: X = A^-1 mod N
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param N Right-hand MPI
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
* MBEDTLS_ERR_MPI_BAD_INPUT_DATA if N is negative or nil
MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N
*/
int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N );
/**
* \brief Miller-Rabin primality test
*
* \param X MPI to check
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successful (probably prime),
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
* MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if X is not prime
*/
int mbedtls_mpi_is_prime( const mbedtls_mpi *X,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Prime number generation
*
* \param X Destination MPI
* \param nbits Required size of X in bits
* ( 3 <= nbits <= MBEDTLS_MPI_MAX_BITS )
* \param dh_flag If 1, then (X-1)/2 will be prime too
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successful (probably prime),
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
* MBEDTLS_ERR_MPI_BAD_INPUT_DATA if nbits is < 3
*/
int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mbedtls_mpi_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* bignum.h */

View file

@ -0,0 +1,203 @@
/**
* \file blowfish.h
*
* \brief Blowfish block cipher
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_BLOWFISH_H
#define MBEDTLS_BLOWFISH_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include <stdint.h>
#define MBEDTLS_BLOWFISH_ENCRYPT 1
#define MBEDTLS_BLOWFISH_DECRYPT 0
#define MBEDTLS_BLOWFISH_MAX_KEY_BITS 448
#define MBEDTLS_BLOWFISH_MIN_KEY_BITS 32
#define MBEDTLS_BLOWFISH_ROUNDS 16 /**< Rounds to use. When increasing this value, make sure to extend the initialisation vectors */
#define MBEDTLS_BLOWFISH_BLOCKSIZE 8 /* Blowfish uses 64 bit blocks */
#define MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH -0x0016 /**< Invalid key length. */
#define MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH -0x0018 /**< Invalid data input length. */
#if !defined(MBEDTLS_BLOWFISH_ALT)
// Regular implementation
//
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Blowfish context structure
*/
typedef struct
{
uint32_t P[MBEDTLS_BLOWFISH_ROUNDS + 2]; /*!< Blowfish round keys */
uint32_t S[4][256]; /*!< key dependent S-boxes */
}
mbedtls_blowfish_context;
/**
* \brief Initialize Blowfish context
*
* \param ctx Blowfish context to be initialized
*/
void mbedtls_blowfish_init( mbedtls_blowfish_context *ctx );
/**
* \brief Clear Blowfish context
*
* \param ctx Blowfish context to be cleared
*/
void mbedtls_blowfish_free( mbedtls_blowfish_context *ctx );
/**
* \brief Blowfish key schedule
*
* \param ctx Blowfish context to be initialized
* \param key encryption key
* \param keybits must be between 32 and 448 bits
*
* \return 0 if successful, or MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH
*/
int mbedtls_blowfish_setkey( mbedtls_blowfish_context *ctx, const unsigned char *key,
unsigned int keybits );
/**
* \brief Blowfish-ECB block encryption/decryption
*
* \param ctx Blowfish context
* \param mode MBEDTLS_BLOWFISH_ENCRYPT or MBEDTLS_BLOWFISH_DECRYPT
* \param input 8-byte input block
* \param output 8-byte output block
*
* \return 0 if successful
*/
int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx,
int mode,
const unsigned char input[MBEDTLS_BLOWFISH_BLOCKSIZE],
unsigned char output[MBEDTLS_BLOWFISH_BLOCKSIZE] );
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/**
* \brief Blowfish-CBC buffer encryption/decryption
* Length should be a multiple of the block
* size (8 bytes)
*
* \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx Blowfish context
* \param mode MBEDTLS_BLOWFISH_ENCRYPT or MBEDTLS_BLOWFISH_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful, or
* MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH
*/
int mbedtls_blowfish_crypt_cbc( mbedtls_blowfish_context *ctx,
int mode,
size_t length,
unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_CIPHER_MODE_CFB)
/**
* \brief Blowfish CFB buffer encryption/decryption.
*
* \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx Blowfish context
* \param mode MBEDTLS_BLOWFISH_ENCRYPT or MBEDTLS_BLOWFISH_DECRYPT
* \param length length of the input data
* \param iv_off offset in IV (updated after use)
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful
*/
int mbedtls_blowfish_crypt_cfb64( mbedtls_blowfish_context *ctx,
int mode,
size_t length,
size_t *iv_off,
unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE],
const unsigned char *input,
unsigned char *output );
#endif /*MBEDTLS_CIPHER_MODE_CFB */
#if defined(MBEDTLS_CIPHER_MODE_CTR)
/**
* \brief Blowfish-CTR buffer encryption/decryption
*
* Warning: You have to keep the maximum use of your counter in mind!
*
* \param ctx Blowfish context
* \param length The length of the data
* \param nc_off The offset in the current stream_block (for resuming
* within current cipher stream). The offset pointer to
* should be 0 at the start of a stream.
* \param nonce_counter The 64-bit nonce and counter.
* \param stream_block The saved stream-block for resuming. Is overwritten
* by the function.
* \param input The input data stream
* \param output The output data stream
*
* \return 0 if successful
*/
int mbedtls_blowfish_crypt_ctr( mbedtls_blowfish_context *ctx,
size_t length,
size_t *nc_off,
unsigned char nonce_counter[MBEDTLS_BLOWFISH_BLOCKSIZE],
unsigned char stream_block[MBEDTLS_BLOWFISH_BLOCKSIZE],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CTR */
#ifdef __cplusplus
}
#endif
#else /* MBEDTLS_BLOWFISH_ALT */
#include "blowfish_alt.h"
#endif /* MBEDTLS_BLOWFISH_ALT */
#endif /* blowfish.h */

View file

@ -0,0 +1,885 @@
/**
* \file bn_mul.h
*
* \brief Multi-precision integer library
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* Multiply source vector [s] with b, add result
* to destination vector [d] and set carry c.
*
* Currently supports:
*
* . IA-32 (386+) . AMD64 / EM64T
* . IA-32 (SSE2) . Motorola 68000
* . PowerPC, 32-bit . MicroBlaze
* . PowerPC, 64-bit . TriCore
* . SPARC v8 . ARM v3+
* . Alpha . MIPS32
* . C, longlong . C, generic
*/
#ifndef MBEDTLS_BN_MUL_H
#define MBEDTLS_BN_MUL_H
#include "bignum.h"
#if defined(MBEDTLS_HAVE_ASM)
#ifndef asm
#define asm __asm
#endif
/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */
#if defined(__GNUC__) && \
( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 )
#if defined(__i386__)
#define MULADDC_INIT \
asm( \
"movl %%ebx, %0 \n\t" \
"movl %5, %%esi \n\t" \
"movl %6, %%edi \n\t" \
"movl %7, %%ecx \n\t" \
"movl %8, %%ebx \n\t"
#define MULADDC_CORE \
"lodsl \n\t" \
"mull %%ebx \n\t" \
"addl %%ecx, %%eax \n\t" \
"adcl $0, %%edx \n\t" \
"addl (%%edi), %%eax \n\t" \
"adcl $0, %%edx \n\t" \
"movl %%edx, %%ecx \n\t" \
"stosl \n\t"
#if defined(MBEDTLS_HAVE_SSE2)
#define MULADDC_HUIT \
"movd %%ecx, %%mm1 \n\t" \
"movd %%ebx, %%mm0 \n\t" \
"movd (%%edi), %%mm3 \n\t" \
"paddq %%mm3, %%mm1 \n\t" \
"movd (%%esi), %%mm2 \n\t" \
"pmuludq %%mm0, %%mm2 \n\t" \
"movd 4(%%esi), %%mm4 \n\t" \
"pmuludq %%mm0, %%mm4 \n\t" \
"movd 8(%%esi), %%mm6 \n\t" \
"pmuludq %%mm0, %%mm6 \n\t" \
"movd 12(%%esi), %%mm7 \n\t" \
"pmuludq %%mm0, %%mm7 \n\t" \
"paddq %%mm2, %%mm1 \n\t" \
"movd 4(%%edi), %%mm3 \n\t" \
"paddq %%mm4, %%mm3 \n\t" \
"movd 8(%%edi), %%mm5 \n\t" \
"paddq %%mm6, %%mm5 \n\t" \
"movd 12(%%edi), %%mm4 \n\t" \
"paddq %%mm4, %%mm7 \n\t" \
"movd %%mm1, (%%edi) \n\t" \
"movd 16(%%esi), %%mm2 \n\t" \
"pmuludq %%mm0, %%mm2 \n\t" \
"psrlq $32, %%mm1 \n\t" \
"movd 20(%%esi), %%mm4 \n\t" \
"pmuludq %%mm0, %%mm4 \n\t" \
"paddq %%mm3, %%mm1 \n\t" \
"movd 24(%%esi), %%mm6 \n\t" \
"pmuludq %%mm0, %%mm6 \n\t" \
"movd %%mm1, 4(%%edi) \n\t" \
"psrlq $32, %%mm1 \n\t" \
"movd 28(%%esi), %%mm3 \n\t" \
"pmuludq %%mm0, %%mm3 \n\t" \
"paddq %%mm5, %%mm1 \n\t" \
"movd 16(%%edi), %%mm5 \n\t" \
"paddq %%mm5, %%mm2 \n\t" \
"movd %%mm1, 8(%%edi) \n\t" \
"psrlq $32, %%mm1 \n\t" \
"paddq %%mm7, %%mm1 \n\t" \
"movd 20(%%edi), %%mm5 \n\t" \
"paddq %%mm5, %%mm4 \n\t" \
"movd %%mm1, 12(%%edi) \n\t" \
"psrlq $32, %%mm1 \n\t" \
"paddq %%mm2, %%mm1 \n\t" \
"movd 24(%%edi), %%mm5 \n\t" \
"paddq %%mm5, %%mm6 \n\t" \
"movd %%mm1, 16(%%edi) \n\t" \
"psrlq $32, %%mm1 \n\t" \
"paddq %%mm4, %%mm1 \n\t" \
"movd 28(%%edi), %%mm5 \n\t" \
"paddq %%mm5, %%mm3 \n\t" \
"movd %%mm1, 20(%%edi) \n\t" \
"psrlq $32, %%mm1 \n\t" \
"paddq %%mm6, %%mm1 \n\t" \
"movd %%mm1, 24(%%edi) \n\t" \
"psrlq $32, %%mm1 \n\t" \
"paddq %%mm3, %%mm1 \n\t" \
"movd %%mm1, 28(%%edi) \n\t" \
"addl $32, %%edi \n\t" \
"addl $32, %%esi \n\t" \
"psrlq $32, %%mm1 \n\t" \
"movd %%mm1, %%ecx \n\t"
#define MULADDC_STOP \
"emms \n\t" \
"movl %4, %%ebx \n\t" \
"movl %%ecx, %1 \n\t" \
"movl %%edi, %2 \n\t" \
"movl %%esi, %3 \n\t" \
: "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
: "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
: "eax", "ecx", "edx", "esi", "edi" \
);
#else
#define MULADDC_STOP \
"movl %4, %%ebx \n\t" \
"movl %%ecx, %1 \n\t" \
"movl %%edi, %2 \n\t" \
"movl %%esi, %3 \n\t" \
: "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
: "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
: "eax", "ecx", "edx", "esi", "edi" \
);
#endif /* SSE2 */
#endif /* i386 */
#if defined(__amd64__) || defined (__x86_64__)
#define MULADDC_INIT \
asm( \
"xorq %%r8, %%r8 \n\t"
#define MULADDC_CORE \
"movq (%%rsi), %%rax \n\t" \
"mulq %%rbx \n\t" \
"addq $8, %%rsi \n\t" \
"addq %%rcx, %%rax \n\t" \
"movq %%r8, %%rcx \n\t" \
"adcq $0, %%rdx \n\t" \
"nop \n\t" \
"addq %%rax, (%%rdi) \n\t" \
"adcq %%rdx, %%rcx \n\t" \
"addq $8, %%rdi \n\t"
#define MULADDC_STOP \
: "+c" (c), "+D" (d), "+S" (s) \
: "b" (b) \
: "rax", "rdx", "r8" \
);
#endif /* AMD64 */
#if defined(__mc68020__) || defined(__mcpu32__)
#define MULADDC_INIT \
asm( \
"movl %3, %%a2 \n\t" \
"movl %4, %%a3 \n\t" \
"movl %5, %%d3 \n\t" \
"movl %6, %%d2 \n\t" \
"moveq #0, %%d0 \n\t"
#define MULADDC_CORE \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d4:%%d1 \n\t" \
"addl %%d3, %%d1 \n\t" \
"addxl %%d0, %%d4 \n\t" \
"moveq #0, %%d3 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"addxl %%d4, %%d3 \n\t"
#define MULADDC_STOP \
"movl %%d3, %0 \n\t" \
"movl %%a3, %1 \n\t" \
"movl %%a2, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "d0", "d1", "d2", "d3", "d4", "a2", "a3" \
);
#define MULADDC_HUIT \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d4:%%d1 \n\t" \
"addxl %%d3, %%d1 \n\t" \
"addxl %%d0, %%d4 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d3:%%d1 \n\t" \
"addxl %%d4, %%d1 \n\t" \
"addxl %%d0, %%d3 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d4:%%d1 \n\t" \
"addxl %%d3, %%d1 \n\t" \
"addxl %%d0, %%d4 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d3:%%d1 \n\t" \
"addxl %%d4, %%d1 \n\t" \
"addxl %%d0, %%d3 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d4:%%d1 \n\t" \
"addxl %%d3, %%d1 \n\t" \
"addxl %%d0, %%d4 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d3:%%d1 \n\t" \
"addxl %%d4, %%d1 \n\t" \
"addxl %%d0, %%d3 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d4:%%d1 \n\t" \
"addxl %%d3, %%d1 \n\t" \
"addxl %%d0, %%d4 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d3:%%d1 \n\t" \
"addxl %%d4, %%d1 \n\t" \
"addxl %%d0, %%d3 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"addxl %%d0, %%d3 \n\t"
#endif /* MC68000 */
#if defined(__powerpc64__) || defined(__ppc64__)
#if defined(__MACH__) && defined(__APPLE__)
#define MULADDC_INIT \
asm( \
"ld r3, %3 \n\t" \
"ld r4, %4 \n\t" \
"ld r5, %5 \n\t" \
"ld r6, %6 \n\t" \
"addi r3, r3, -8 \n\t" \
"addi r4, r4, -8 \n\t" \
"addic r5, r5, 0 \n\t"
#define MULADDC_CORE \
"ldu r7, 8(r3) \n\t" \
"mulld r8, r7, r6 \n\t" \
"mulhdu r9, r7, r6 \n\t" \
"adde r8, r8, r5 \n\t" \
"ld r7, 8(r4) \n\t" \
"addze r5, r9 \n\t" \
"addc r8, r8, r7 \n\t" \
"stdu r8, 8(r4) \n\t"
#define MULADDC_STOP \
"addze r5, r5 \n\t" \
"addi r4, r4, 8 \n\t" \
"addi r3, r3, 8 \n\t" \
"std r5, %0 \n\t" \
"std r4, %1 \n\t" \
"std r3, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r3", "r4", "r5", "r6", "r7", "r8", "r9" \
);
#else /* __MACH__ && __APPLE__ */
#define MULADDC_INIT \
asm( \
"ld %%r3, %3 \n\t" \
"ld %%r4, %4 \n\t" \
"ld %%r5, %5 \n\t" \
"ld %%r6, %6 \n\t" \
"addi %%r3, %%r3, -8 \n\t" \
"addi %%r4, %%r4, -8 \n\t" \
"addic %%r5, %%r5, 0 \n\t"
#define MULADDC_CORE \
"ldu %%r7, 8(%%r3) \n\t" \
"mulld %%r8, %%r7, %%r6 \n\t" \
"mulhdu %%r9, %%r7, %%r6 \n\t" \
"adde %%r8, %%r8, %%r5 \n\t" \
"ld %%r7, 8(%%r4) \n\t" \
"addze %%r5, %%r9 \n\t" \
"addc %%r8, %%r8, %%r7 \n\t" \
"stdu %%r8, 8(%%r4) \n\t"
#define MULADDC_STOP \
"addze %%r5, %%r5 \n\t" \
"addi %%r4, %%r4, 8 \n\t" \
"addi %%r3, %%r3, 8 \n\t" \
"std %%r5, %0 \n\t" \
"std %%r4, %1 \n\t" \
"std %%r3, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r3", "r4", "r5", "r6", "r7", "r8", "r9" \
);
#endif /* __MACH__ && __APPLE__ */
#elif defined(__powerpc__) || defined(__ppc__) /* end PPC64/begin PPC32 */
#if defined(__MACH__) && defined(__APPLE__)
#define MULADDC_INIT \
asm( \
"lwz r3, %3 \n\t" \
"lwz r4, %4 \n\t" \
"lwz r5, %5 \n\t" \
"lwz r6, %6 \n\t" \
"addi r3, r3, -4 \n\t" \
"addi r4, r4, -4 \n\t" \
"addic r5, r5, 0 \n\t"
#define MULADDC_CORE \
"lwzu r7, 4(r3) \n\t" \
"mullw r8, r7, r6 \n\t" \
"mulhwu r9, r7, r6 \n\t" \
"adde r8, r8, r5 \n\t" \
"lwz r7, 4(r4) \n\t" \
"addze r5, r9 \n\t" \
"addc r8, r8, r7 \n\t" \
"stwu r8, 4(r4) \n\t"
#define MULADDC_STOP \
"addze r5, r5 \n\t" \
"addi r4, r4, 4 \n\t" \
"addi r3, r3, 4 \n\t" \
"stw r5, %0 \n\t" \
"stw r4, %1 \n\t" \
"stw r3, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r3", "r4", "r5", "r6", "r7", "r8", "r9" \
);
#else /* __MACH__ && __APPLE__ */
#define MULADDC_INIT \
asm( \
"lwz %%r3, %3 \n\t" \
"lwz %%r4, %4 \n\t" \
"lwz %%r5, %5 \n\t" \
"lwz %%r6, %6 \n\t" \
"addi %%r3, %%r3, -4 \n\t" \
"addi %%r4, %%r4, -4 \n\t" \
"addic %%r5, %%r5, 0 \n\t"
#define MULADDC_CORE \
"lwzu %%r7, 4(%%r3) \n\t" \
"mullw %%r8, %%r7, %%r6 \n\t" \
"mulhwu %%r9, %%r7, %%r6 \n\t" \
"adde %%r8, %%r8, %%r5 \n\t" \
"lwz %%r7, 4(%%r4) \n\t" \
"addze %%r5, %%r9 \n\t" \
"addc %%r8, %%r8, %%r7 \n\t" \
"stwu %%r8, 4(%%r4) \n\t"
#define MULADDC_STOP \
"addze %%r5, %%r5 \n\t" \
"addi %%r4, %%r4, 4 \n\t" \
"addi %%r3, %%r3, 4 \n\t" \
"stw %%r5, %0 \n\t" \
"stw %%r4, %1 \n\t" \
"stw %%r3, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r3", "r4", "r5", "r6", "r7", "r8", "r9" \
);
#endif /* __MACH__ && __APPLE__ */
#endif /* PPC32 */
/*
* The Sparc(64) assembly is reported to be broken.
* Disable it for now, until we're able to fix it.
*/
#if 0 && defined(__sparc__)
#if defined(__sparc64__)
#define MULADDC_INIT \
asm( \
"ldx %3, %%o0 \n\t" \
"ldx %4, %%o1 \n\t" \
"ld %5, %%o2 \n\t" \
"ld %6, %%o3 \n\t"
#define MULADDC_CORE \
"ld [%%o0], %%o4 \n\t" \
"inc 4, %%o0 \n\t" \
"ld [%%o1], %%o5 \n\t" \
"umul %%o3, %%o4, %%o4 \n\t" \
"addcc %%o4, %%o2, %%o4 \n\t" \
"rd %%y, %%g1 \n\t" \
"addx %%g1, 0, %%g1 \n\t" \
"addcc %%o4, %%o5, %%o4 \n\t" \
"st %%o4, [%%o1] \n\t" \
"addx %%g1, 0, %%o2 \n\t" \
"inc 4, %%o1 \n\t"
#define MULADDC_STOP \
"st %%o2, %0 \n\t" \
"stx %%o1, %1 \n\t" \
"stx %%o0, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "g1", "o0", "o1", "o2", "o3", "o4", \
"o5" \
);
#else /* __sparc64__ */
#define MULADDC_INIT \
asm( \
"ld %3, %%o0 \n\t" \
"ld %4, %%o1 \n\t" \
"ld %5, %%o2 \n\t" \
"ld %6, %%o3 \n\t"
#define MULADDC_CORE \
"ld [%%o0], %%o4 \n\t" \
"inc 4, %%o0 \n\t" \
"ld [%%o1], %%o5 \n\t" \
"umul %%o3, %%o4, %%o4 \n\t" \
"addcc %%o4, %%o2, %%o4 \n\t" \
"rd %%y, %%g1 \n\t" \
"addx %%g1, 0, %%g1 \n\t" \
"addcc %%o4, %%o5, %%o4 \n\t" \
"st %%o4, [%%o1] \n\t" \
"addx %%g1, 0, %%o2 \n\t" \
"inc 4, %%o1 \n\t"
#define MULADDC_STOP \
"st %%o2, %0 \n\t" \
"st %%o1, %1 \n\t" \
"st %%o0, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "g1", "o0", "o1", "o2", "o3", "o4", \
"o5" \
);
#endif /* __sparc64__ */
#endif /* __sparc__ */
#if defined(__microblaze__) || defined(microblaze)
#define MULADDC_INIT \
asm( \
"lwi r3, %3 \n\t" \
"lwi r4, %4 \n\t" \
"lwi r5, %5 \n\t" \
"lwi r6, %6 \n\t" \
"andi r7, r6, 0xffff \n\t" \
"bsrli r6, r6, 16 \n\t"
#define MULADDC_CORE \
"lhui r8, r3, 0 \n\t" \
"addi r3, r3, 2 \n\t" \
"lhui r9, r3, 0 \n\t" \
"addi r3, r3, 2 \n\t" \
"mul r10, r9, r6 \n\t" \
"mul r11, r8, r7 \n\t" \
"mul r12, r9, r7 \n\t" \
"mul r13, r8, r6 \n\t" \
"bsrli r8, r10, 16 \n\t" \
"bsrli r9, r11, 16 \n\t" \
"add r13, r13, r8 \n\t" \
"add r13, r13, r9 \n\t" \
"bslli r10, r10, 16 \n\t" \
"bslli r11, r11, 16 \n\t" \
"add r12, r12, r10 \n\t" \
"addc r13, r13, r0 \n\t" \
"add r12, r12, r11 \n\t" \
"addc r13, r13, r0 \n\t" \
"lwi r10, r4, 0 \n\t" \
"add r12, r12, r10 \n\t" \
"addc r13, r13, r0 \n\t" \
"add r12, r12, r5 \n\t" \
"addc r5, r13, r0 \n\t" \
"swi r12, r4, 0 \n\t" \
"addi r4, r4, 4 \n\t"
#define MULADDC_STOP \
"swi r5, %0 \n\t" \
"swi r4, %1 \n\t" \
"swi r3, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r3", "r4" "r5", "r6", "r7", "r8", \
"r9", "r10", "r11", "r12", "r13" \
);
#endif /* MicroBlaze */
#if defined(__tricore__)
#define MULADDC_INIT \
asm( \
"ld.a %%a2, %3 \n\t" \
"ld.a %%a3, %4 \n\t" \
"ld.w %%d4, %5 \n\t" \
"ld.w %%d1, %6 \n\t" \
"xor %%d5, %%d5 \n\t"
#define MULADDC_CORE \
"ld.w %%d0, [%%a2+] \n\t" \
"madd.u %%e2, %%e4, %%d0, %%d1 \n\t" \
"ld.w %%d0, [%%a3] \n\t" \
"addx %%d2, %%d2, %%d0 \n\t" \
"addc %%d3, %%d3, 0 \n\t" \
"mov %%d4, %%d3 \n\t" \
"st.w [%%a3+], %%d2 \n\t"
#define MULADDC_STOP \
"st.w %0, %%d4 \n\t" \
"st.a %1, %%a3 \n\t" \
"st.a %2, %%a2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "d0", "d1", "e2", "d4", "a2", "a3" \
);
#endif /* TriCore */
/*
* gcc -O0 by default uses r7 for the frame pointer, so it complains about our
* use of r7 below, unless -fomit-frame-pointer is passed. Unfortunately,
* passing that option is not easy when building with yotta.
*
* On the other hand, -fomit-frame-pointer is implied by any -Ox options with
* x !=0, which we can detect using __OPTIMIZE__ (which is also defined by
* clang and armcc5 under the same conditions).
*
* So, only use the optimized assembly below for optimized build, which avoids
* the build error and is pretty reasonable anyway.
*/
#if defined(__GNUC__) && !defined(__OPTIMIZE__)
#define MULADDC_CANNOT_USE_R7
#endif
#if defined(__arm__) && !defined(MULADDC_CANNOT_USE_R7)
#if defined(__thumb__) && !defined(__thumb2__)
#define MULADDC_INIT \
asm( \
"ldr r0, %3 \n\t" \
"ldr r1, %4 \n\t" \
"ldr r2, %5 \n\t" \
"ldr r3, %6 \n\t" \
"lsr r7, r3, #16 \n\t" \
"mov r9, r7 \n\t" \
"lsl r7, r3, #16 \n\t" \
"lsr r7, r7, #16 \n\t" \
"mov r8, r7 \n\t"
#define MULADDC_CORE \
"ldmia r0!, {r6} \n\t" \
"lsr r7, r6, #16 \n\t" \
"lsl r6, r6, #16 \n\t" \
"lsr r6, r6, #16 \n\t" \
"mov r4, r8 \n\t" \
"mul r4, r6 \n\t" \
"mov r3, r9 \n\t" \
"mul r6, r3 \n\t" \
"mov r5, r9 \n\t" \
"mul r5, r7 \n\t" \
"mov r3, r8 \n\t" \
"mul r7, r3 \n\t" \
"lsr r3, r6, #16 \n\t" \
"add r5, r5, r3 \n\t" \
"lsr r3, r7, #16 \n\t" \
"add r5, r5, r3 \n\t" \
"add r4, r4, r2 \n\t" \
"mov r2, #0 \n\t" \
"adc r5, r2 \n\t" \
"lsl r3, r6, #16 \n\t" \
"add r4, r4, r3 \n\t" \
"adc r5, r2 \n\t" \
"lsl r3, r7, #16 \n\t" \
"add r4, r4, r3 \n\t" \
"adc r5, r2 \n\t" \
"ldr r3, [r1] \n\t" \
"add r4, r4, r3 \n\t" \
"adc r2, r5 \n\t" \
"stmia r1!, {r4} \n\t"
#define MULADDC_STOP \
"str r2, %0 \n\t" \
"str r1, %1 \n\t" \
"str r0, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r0", "r1", "r2", "r3", "r4", "r5", \
"r6", "r7", "r8", "r9", "cc" \
);
#else
#define MULADDC_INIT \
asm( \
"ldr r0, %3 \n\t" \
"ldr r1, %4 \n\t" \
"ldr r2, %5 \n\t" \
"ldr r3, %6 \n\t"
#define MULADDC_CORE \
"ldr r4, [r0], #4 \n\t" \
"mov r5, #0 \n\t" \
"ldr r6, [r1] \n\t" \
"umlal r2, r5, r3, r4 \n\t" \
"adds r7, r6, r2 \n\t" \
"adc r2, r5, #0 \n\t" \
"str r7, [r1], #4 \n\t"
#define MULADDC_STOP \
"str r2, %0 \n\t" \
"str r1, %1 \n\t" \
"str r0, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r0", "r1", "r2", "r3", "r4", "r5", \
"r6", "r7", "cc" \
);
#endif /* Thumb */
#endif /* ARMv3 */
#if defined(__alpha__)
#define MULADDC_INIT \
asm( \
"ldq $1, %3 \n\t" \
"ldq $2, %4 \n\t" \
"ldq $3, %5 \n\t" \
"ldq $4, %6 \n\t"
#define MULADDC_CORE \
"ldq $6, 0($1) \n\t" \
"addq $1, 8, $1 \n\t" \
"mulq $6, $4, $7 \n\t" \
"umulh $6, $4, $6 \n\t" \
"addq $7, $3, $7 \n\t" \
"cmpult $7, $3, $3 \n\t" \
"ldq $5, 0($2) \n\t" \
"addq $7, $5, $7 \n\t" \
"cmpult $7, $5, $5 \n\t" \
"stq $7, 0($2) \n\t" \
"addq $2, 8, $2 \n\t" \
"addq $6, $3, $3 \n\t" \
"addq $5, $3, $3 \n\t"
#define MULADDC_STOP \
"stq $3, %0 \n\t" \
"stq $2, %1 \n\t" \
"stq $1, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "$1", "$2", "$3", "$4", "$5", "$6", "$7" \
);
#endif /* Alpha */
#if defined(__mips__) && !defined(__mips64)
#define MULADDC_INIT \
asm( \
"lw $10, %3 \n\t" \
"lw $11, %4 \n\t" \
"lw $12, %5 \n\t" \
"lw $13, %6 \n\t"
#define MULADDC_CORE \
"lw $14, 0($10) \n\t" \
"multu $13, $14 \n\t" \
"addi $10, $10, 4 \n\t" \
"mflo $14 \n\t" \
"mfhi $9 \n\t" \
"addu $14, $12, $14 \n\t" \
"lw $15, 0($11) \n\t" \
"sltu $12, $14, $12 \n\t" \
"addu $15, $14, $15 \n\t" \
"sltu $14, $15, $14 \n\t" \
"addu $12, $12, $9 \n\t" \
"sw $15, 0($11) \n\t" \
"addu $12, $12, $14 \n\t" \
"addi $11, $11, 4 \n\t"
#define MULADDC_STOP \
"sw $12, %0 \n\t" \
"sw $11, %1 \n\t" \
"sw $10, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "$9", "$10", "$11", "$12", "$13", "$14", "$15" \
);
#endif /* MIPS */
#endif /* GNUC */
#if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
#define MULADDC_INIT \
__asm mov esi, s \
__asm mov edi, d \
__asm mov ecx, c \
__asm mov ebx, b
#define MULADDC_CORE \
__asm lodsd \
__asm mul ebx \
__asm add eax, ecx \
__asm adc edx, 0 \
__asm add eax, [edi] \
__asm adc edx, 0 \
__asm mov ecx, edx \
__asm stosd
#if defined(MBEDTLS_HAVE_SSE2)
#define EMIT __asm _emit
#define MULADDC_HUIT \
EMIT 0x0F EMIT 0x6E EMIT 0xC9 \
EMIT 0x0F EMIT 0x6E EMIT 0xC3 \
EMIT 0x0F EMIT 0x6E EMIT 0x1F \
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
EMIT 0x0F EMIT 0x6E EMIT 0x16 \
EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x04 \
EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x08 \
EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
EMIT 0x0F EMIT 0x6E EMIT 0x7E EMIT 0x0C \
EMIT 0x0F EMIT 0xF4 EMIT 0xF8 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
EMIT 0x0F EMIT 0x6E EMIT 0x5F EMIT 0x04 \
EMIT 0x0F EMIT 0xD4 EMIT 0xDC \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x08 \
EMIT 0x0F EMIT 0xD4 EMIT 0xEE \
EMIT 0x0F EMIT 0x6E EMIT 0x67 EMIT 0x0C \
EMIT 0x0F EMIT 0xD4 EMIT 0xFC \
EMIT 0x0F EMIT 0x7E EMIT 0x0F \
EMIT 0x0F EMIT 0x6E EMIT 0x56 EMIT 0x10 \
EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x14 \
EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x18 \
EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x04 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0x6E EMIT 0x5E EMIT 0x1C \
EMIT 0x0F EMIT 0xF4 EMIT 0xD8 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCD \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x10 \
EMIT 0x0F EMIT 0xD4 EMIT 0xD5 \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x08 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCF \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x14 \
EMIT 0x0F EMIT 0xD4 EMIT 0xE5 \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x0C \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x18 \
EMIT 0x0F EMIT 0xD4 EMIT 0xF5 \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x10 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCC \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x1C \
EMIT 0x0F EMIT 0xD4 EMIT 0xDD \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x14 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCE \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x18 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x1C \
EMIT 0x83 EMIT 0xC7 EMIT 0x20 \
EMIT 0x83 EMIT 0xC6 EMIT 0x20 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0x7E EMIT 0xC9
#define MULADDC_STOP \
EMIT 0x0F EMIT 0x77 \
__asm mov c, ecx \
__asm mov d, edi \
__asm mov s, esi \
#else
#define MULADDC_STOP \
__asm mov c, ecx \
__asm mov d, edi \
__asm mov s, esi \
#endif /* SSE2 */
#endif /* MSVC */
#endif /* MBEDTLS_HAVE_ASM */
#if !defined(MULADDC_CORE)
#if defined(MBEDTLS_HAVE_UDBL)
#define MULADDC_INIT \
{ \
mbedtls_t_udbl r; \
mbedtls_mpi_uint r0, r1;
#define MULADDC_CORE \
r = *(s++) * (mbedtls_t_udbl) b; \
r0 = (mbedtls_mpi_uint) r; \
r1 = (mbedtls_mpi_uint)( r >> biL ); \
r0 += c; r1 += (r0 < c); \
r0 += *d; r1 += (r0 < *d); \
c = r1; *(d++) = r0;
#define MULADDC_STOP \
}
#else
#define MULADDC_INIT \
{ \
mbedtls_mpi_uint s0, s1, b0, b1; \
mbedtls_mpi_uint r0, r1, rx, ry; \
b0 = ( b << biH ) >> biH; \
b1 = ( b >> biH );
#define MULADDC_CORE \
s0 = ( *s << biH ) >> biH; \
s1 = ( *s >> biH ); s++; \
rx = s0 * b1; r0 = s0 * b0; \
ry = s1 * b0; r1 = s1 * b1; \
r1 += ( rx >> biH ); \
r1 += ( ry >> biH ); \
rx <<= biH; ry <<= biH; \
r0 += rx; r1 += (r0 < rx); \
r0 += ry; r1 += (r0 < ry); \
r0 += c; r1 += (r0 < c); \
r0 += *d; r1 += (r0 < *d); \
c = r1; *(d++) = r0;
#define MULADDC_STOP \
}
#endif /* C (generic) */
#endif /* C (longlong) */
#endif /* bn_mul.h */

View file

@ -0,0 +1,235 @@
/**
* \file camellia.h
*
* \brief Camellia block cipher
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_CAMELLIA_H
#define MBEDTLS_CAMELLIA_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include <stdint.h>
#define MBEDTLS_CAMELLIA_ENCRYPT 1
#define MBEDTLS_CAMELLIA_DECRYPT 0
#define MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH -0x0024 /**< Invalid key length. */
#define MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH -0x0026 /**< Invalid data input length. */
#if !defined(MBEDTLS_CAMELLIA_ALT)
// Regular implementation
//
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief CAMELLIA context structure
*/
typedef struct
{
int nr; /*!< number of rounds */
uint32_t rk[68]; /*!< CAMELLIA round keys */
}
mbedtls_camellia_context;
/**
* \brief Initialize CAMELLIA context
*
* \param ctx CAMELLIA context to be initialized
*/
void mbedtls_camellia_init( mbedtls_camellia_context *ctx );
/**
* \brief Clear CAMELLIA context
*
* \param ctx CAMELLIA context to be cleared
*/
void mbedtls_camellia_free( mbedtls_camellia_context *ctx );
/**
* \brief CAMELLIA key schedule (encryption)
*
* \param ctx CAMELLIA context to be initialized
* \param key encryption key
* \param keybits must be 128, 192 or 256
*
* \return 0 if successful, or MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH
*/
int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx, const unsigned char *key,
unsigned int keybits );
/**
* \brief CAMELLIA key schedule (decryption)
*
* \param ctx CAMELLIA context to be initialized
* \param key decryption key
* \param keybits must be 128, 192 or 256
*
* \return 0 if successful, or MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH
*/
int mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx, const unsigned char *key,
unsigned int keybits );
/**
* \brief CAMELLIA-ECB block encryption/decryption
*
* \param ctx CAMELLIA context
* \param mode MBEDTLS_CAMELLIA_ENCRYPT or MBEDTLS_CAMELLIA_DECRYPT
* \param input 16-byte input block
* \param output 16-byte output block
*
* \return 0 if successful
*/
int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16] );
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/**
* \brief CAMELLIA-CBC buffer encryption/decryption
* Length should be a multiple of the block
* size (16 bytes)
*
* \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx CAMELLIA context
* \param mode MBEDTLS_CAMELLIA_ENCRYPT or MBEDTLS_CAMELLIA_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful, or
* MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH
*/
int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx,
int mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_CIPHER_MODE_CFB)
/**
* \brief CAMELLIA-CFB128 buffer encryption/decryption
*
* Note: Due to the nature of CFB you should use the same key schedule for
* both encryption and decryption. So a context initialized with
* mbedtls_camellia_setkey_enc() for both MBEDTLS_CAMELLIA_ENCRYPT and CAMELLIE_DECRYPT.
*
* \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx CAMELLIA context
* \param mode MBEDTLS_CAMELLIA_ENCRYPT or MBEDTLS_CAMELLIA_DECRYPT
* \param length length of the input data
* \param iv_off offset in IV (updated after use)
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful, or
* MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH
*/
int mbedtls_camellia_crypt_cfb128( mbedtls_camellia_context *ctx,
int mode,
size_t length,
size_t *iv_off,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CFB */
#if defined(MBEDTLS_CIPHER_MODE_CTR)
/**
* \brief CAMELLIA-CTR buffer encryption/decryption
*
* Warning: You have to keep the maximum use of your counter in mind!
*
* Note: Due to the nature of CTR you should use the same key schedule for
* both encryption and decryption. So a context initialized with
* mbedtls_camellia_setkey_enc() for both MBEDTLS_CAMELLIA_ENCRYPT and MBEDTLS_CAMELLIA_DECRYPT.
*
* \param ctx CAMELLIA context
* \param length The length of the data
* \param nc_off The offset in the current stream_block (for resuming
* within current cipher stream). The offset pointer to
* should be 0 at the start of a stream.
* \param nonce_counter The 128-bit nonce and counter.
* \param stream_block The saved stream-block for resuming. Is overwritten
* by the function.
* \param input The input data stream
* \param output The output data stream
*
* \return 0 if successful
*/
int mbedtls_camellia_crypt_ctr( mbedtls_camellia_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 );
#endif /* MBEDTLS_CIPHER_MODE_CTR */
#ifdef __cplusplus
}
#endif
#else /* MBEDTLS_CAMELLIA_ALT */
#include "camellia_alt.h"
#endif /* MBEDTLS_CAMELLIA_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mbedtls_camellia_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* camellia.h */

View file

@ -0,0 +1,141 @@
/**
* \file ccm.h
*
* \brief Counter with CBC-MAC (CCM) for 128-bit block ciphers
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_CCM_H
#define MBEDTLS_CCM_H
#include "cipher.h"
#define MBEDTLS_ERR_CCM_BAD_INPUT -0x000D /**< Bad input parameters to function. */
#define MBEDTLS_ERR_CCM_AUTH_FAILED -0x000F /**< Authenticated decryption failed. */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief CCM context structure
*/
typedef struct {
mbedtls_cipher_context_t cipher_ctx; /*!< cipher context used */
}
mbedtls_ccm_context;
/**
* \brief Initialize CCM context (just makes references valid)
* Makes the context ready for mbedtls_ccm_setkey() or
* mbedtls_ccm_free().
*
* \param ctx CCM context to initialize
*/
void mbedtls_ccm_init( mbedtls_ccm_context *ctx );
/**
* \brief CCM initialization (encryption and decryption)
*
* \param ctx CCM context to be initialized
* \param cipher cipher to use (a 128-bit block cipher)
* \param key encryption key
* \param keybits key size in bits (must be acceptable by the cipher)
*
* \return 0 if successful, or a cipher specific error code
*/
int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
mbedtls_cipher_id_t cipher,
const unsigned char *key,
unsigned int keybits );
/**
* \brief Free a CCM context and underlying cipher sub-context
*
* \param ctx CCM context to free
*/
void mbedtls_ccm_free( mbedtls_ccm_context *ctx );
/**
* \brief CCM buffer encryption
*
* \param ctx CCM context
* \param length length of the input data in bytes
* \param iv nonce (initialization vector)
* \param iv_len length of IV in bytes
* must be 2, 3, 4, 5, 6, 7 or 8
* \param add additional data
* \param add_len length of additional data in bytes
* must be less than 2^16 - 2^8
* \param input buffer holding the input data
* \param output buffer for holding the output data
* must be at least 'length' bytes wide
* \param tag buffer for holding the tag
* \param tag_len length of the tag to generate in bytes
* must be 4, 6, 8, 10, 14 or 16
*
* \note The tag is written to a separate buffer. To get the tag
* concatenated with the output as in the CCM spec, use
* tag = output + length and make sure the output buffer is
* at least length + tag_len wide.
*
* \return 0 if successful
*/
int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
const unsigned char *iv, size_t iv_len,
const unsigned char *add, size_t add_len,
const unsigned char *input, unsigned char *output,
unsigned char *tag, size_t tag_len );
/**
* \brief CCM buffer authenticated decryption
*
* \param ctx CCM context
* \param length length of the input data
* \param iv initialization vector
* \param iv_len length of IV
* \param add additional data
* \param add_len length of additional data
* \param input buffer holding the input data
* \param output buffer for holding the output data
* \param tag buffer holding the tag
* \param tag_len length of the tag
*
* \return 0 if successful and authenticated,
* MBEDTLS_ERR_CCM_AUTH_FAILED if tag does not match
*/
int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
const unsigned char *iv, size_t iv_len,
const unsigned char *add, size_t add_len,
const unsigned char *input, unsigned char *output,
const unsigned char *tag, size_t tag_len );
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mbedtls_ccm_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_CCM_H */

View file

@ -0,0 +1,99 @@
/**
* \file certs.h
*
* \brief Sample certificates and DHM parameters for testing
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_CERTS_H
#define MBEDTLS_CERTS_H
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(MBEDTLS_PEM_PARSE_C)
/* Concatenation of all CA certificates in PEM format if available */
extern const char mbedtls_test_cas_pem[];
extern const size_t mbedtls_test_cas_pem_len;
#endif
/* List of all CA certificates, terminated by NULL */
extern const char * mbedtls_test_cas[];
extern const size_t mbedtls_test_cas_len[];
/*
* Convenience for users who just want a certificate:
* RSA by default, or ECDSA if RSA is not available
*/
extern const char * mbedtls_test_ca_crt;
extern const size_t mbedtls_test_ca_crt_len;
extern const char * mbedtls_test_ca_key;
extern const size_t mbedtls_test_ca_key_len;
extern const char * mbedtls_test_ca_pwd;
extern const size_t mbedtls_test_ca_pwd_len;
extern const char * mbedtls_test_srv_crt;
extern const size_t mbedtls_test_srv_crt_len;
extern const char * mbedtls_test_srv_key;
extern const size_t mbedtls_test_srv_key_len;
extern const char * mbedtls_test_cli_crt;
extern const size_t mbedtls_test_cli_crt_len;
extern const char * mbedtls_test_cli_key;
extern const size_t mbedtls_test_cli_key_len;
#if defined(MBEDTLS_ECDSA_C)
extern const char mbedtls_test_ca_crt_ec[];
extern const size_t mbedtls_test_ca_crt_ec_len;
extern const char mbedtls_test_ca_key_ec[];
extern const size_t mbedtls_test_ca_key_ec_len;
extern const char mbedtls_test_ca_pwd_ec[];
extern const size_t mbedtls_test_ca_pwd_ec_len;
extern const char mbedtls_test_srv_crt_ec[];
extern const size_t mbedtls_test_srv_crt_ec_len;
extern const char mbedtls_test_srv_key_ec[];
extern const size_t mbedtls_test_srv_key_ec_len;
extern const char mbedtls_test_cli_crt_ec[];
extern const size_t mbedtls_test_cli_crt_ec_len;
extern const char mbedtls_test_cli_key_ec[];
extern const size_t mbedtls_test_cli_key_ec_len;
#endif
#if defined(MBEDTLS_RSA_C)
extern const char mbedtls_test_ca_crt_rsa[];
extern const size_t mbedtls_test_ca_crt_rsa_len;
extern const char mbedtls_test_ca_key_rsa[];
extern const size_t mbedtls_test_ca_key_rsa_len;
extern const char mbedtls_test_ca_pwd_rsa[];
extern const size_t mbedtls_test_ca_pwd_rsa_len;
extern const char mbedtls_test_srv_crt_rsa[];
extern const size_t mbedtls_test_srv_crt_rsa_len;
extern const char mbedtls_test_srv_key_rsa[];
extern const size_t mbedtls_test_srv_key_rsa_len;
extern const char mbedtls_test_cli_crt_rsa[];
extern const size_t mbedtls_test_cli_crt_rsa_len;
extern const char mbedtls_test_cli_key_rsa[];
extern const size_t mbedtls_test_cli_key_rsa_len;
#endif
#ifdef __cplusplus
}
#endif
#endif /* certs.h */

View file

@ -0,0 +1,662 @@
/**
* \file check_config.h
*
* \brief Consistency checks for configuration options
*
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* It is recommended to include this file from your config.h
* in order to catch dependency issues early.
*/
#ifndef MBEDTLS_CHECK_CONFIG_H
#define MBEDTLS_CHECK_CONFIG_H
/*
* We assume CHAR_BIT is 8 in many places. In practice, this is true on our
* target platforms, so not an issue, but let's just be extra sure.
*/
#include <limits.h>
#if CHAR_BIT != 8
#error "mbed TLS requires a platform with 8-bit chars"
#endif
#if defined(_WIN32)
#if !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_C is required on Windows"
#endif
/* Fix the config here. Not convenient to put an #ifdef _WIN32 in config.h as
* it would confuse config.pl. */
#if !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && \
!defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO)
#define MBEDTLS_PLATFORM_SNPRINTF_ALT
#endif
#endif /* _WIN32 */
#if defined(TARGET_LIKE_MBED) && \
( defined(MBEDTLS_NET_C) || defined(MBEDTLS_TIMING_C) )
#error "The NET and TIMING modules are not available for mbed OS - please use the network and timing functions provided by mbed OS"
#endif
#if defined(MBEDTLS_DEPRECATED_WARNING) && \
!defined(__GNUC__) && !defined(__clang__)
#error "MBEDTLS_DEPRECATED_WARNING only works with GCC and Clang"
#endif
#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_HAVE_TIME)
#error "MBEDTLS_HAVE_TIME_DATE without MBEDTLS_HAVE_TIME does not make sense"
#endif
#if defined(MBEDTLS_AESNI_C) && !defined(MBEDTLS_HAVE_ASM)
#error "MBEDTLS_AESNI_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_AES_C)
#error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_DHM_C) && !defined(MBEDTLS_BIGNUM_C)
#error "MBEDTLS_DHM_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_CMAC_C) && \
!defined(MBEDTLS_AES_C) && !defined(MBEDTLS_DES_C)
#error "MBEDTLS_CMAC_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECDH_C) && !defined(MBEDTLS_ECP_C)
#error "MBEDTLS_ECDH_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECDSA_C) && \
( !defined(MBEDTLS_ECP_C) || \
!defined(MBEDTLS_ASN1_PARSE_C) || \
!defined(MBEDTLS_ASN1_WRITE_C) )
#error "MBEDTLS_ECDSA_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECJPAKE_C) && \
( !defined(MBEDTLS_ECP_C) || !defined(MBEDTLS_MD_C) )
#error "MBEDTLS_ECJPAKE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C)
#error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || ( \
!defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) ) )
#error "MBEDTLS_ECP_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ENTROPY_C) && (!defined(MBEDTLS_SHA512_C) && \
!defined(MBEDTLS_SHA256_C))
#error "MBEDTLS_ENTROPY_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_SHA512_C) && \
defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 64)
#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high"
#endif
#if defined(MBEDTLS_ENTROPY_C) && \
( !defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_ENTROPY_FORCE_SHA256) ) \
&& defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 32)
#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high"
#endif
#if defined(MBEDTLS_ENTROPY_C) && \
defined(MBEDTLS_ENTROPY_FORCE_SHA256) && !defined(MBEDTLS_SHA256_C)
#error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \
( !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) )
#error "MBEDTLS_TEST_NULL_ENTROPY defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \
( defined(MBEDTLS_ENTROPY_NV_SEED) || defined(MBEDTLS_ENTROPY_HARDWARE_ALT) || \
defined(MBEDTLS_HAVEGE_C) )
#error "MBEDTLS_TEST_NULL_ENTROPY defined, but entropy sources too"
#endif
#if defined(MBEDTLS_GCM_C) && ( \
!defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) )
#error "MBEDTLS_GCM_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT)
#error "MBEDTLS_ECP_RANDOMIZE_JAC_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT)
#error "MBEDTLS_ECP_ADD_MIXED_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT)
#error "MBEDTLS_ECP_DOUBLE_JAC_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT)
#error "MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT)
#error "MBEDTLS_ECP_NORMALIZE_JAC_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT)
#error "MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT)
#error "MBEDTLS_ECP_RANDOMIZE_MXZ_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT)
#error "MBEDTLS_ECP_NORMALIZE_MXZ_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_HAVEGE_C) && !defined(MBEDTLS_TIMING_C)
#error "MBEDTLS_HAVEGE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_HMAC_DRBG_C) && !defined(MBEDTLS_MD_C)
#error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) && !defined(MBEDTLS_DHM_C)
#error "MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) && \
!defined(MBEDTLS_ECDH_C)
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
( !defined(MBEDTLS_DHM_C) || !defined(MBEDTLS_RSA_C) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) )
#error "MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_RSA_C) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) )
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDSA_C) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) && \
( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \
!defined(MBEDTLS_PKCS1_V15) )
#error "MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \
!defined(MBEDTLS_PKCS1_V15) )
#error "MBEDTLS_KEY_EXCHANGE_RSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
( !defined(MBEDTLS_ECJPAKE_C) || !defined(MBEDTLS_SHA256_C) || \
!defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) )
#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) )
#error "MBEDTLS_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PADLOCK_C) && !defined(MBEDTLS_HAVE_ASM)
#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PEM_PARSE_C) && !defined(MBEDTLS_BASE64_C)
#error "MBEDTLS_PEM_PARSE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PEM_WRITE_C) && !defined(MBEDTLS_BASE64_C)
#error "MBEDTLS_PEM_WRITE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PK_C) && \
( !defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_ECP_C) )
#error "MBEDTLS_PK_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_PK_C)
#error "MBEDTLS_PK_PARSE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PK_WRITE_C) && !defined(MBEDTLS_PK_C)
#error "MBEDTLS_PK_WRITE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PKCS11_C) && !defined(MBEDTLS_PK_C)
#error "MBEDTLS_PKCS11_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_EXIT_ALT) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_EXIT_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_EXIT_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) &&\
( defined(MBEDTLS_PLATFORM_STD_EXIT) ||\
defined(MBEDTLS_PLATFORM_EXIT_ALT) )
#error "MBEDTLS_PLATFORM_EXIT_MACRO and MBEDTLS_PLATFORM_STD_EXIT/MBEDTLS_PLATFORM_EXIT_ALT cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_TIME_ALT) &&\
( !defined(MBEDTLS_PLATFORM_C) ||\
!defined(MBEDTLS_HAVE_TIME) )
#error "MBEDTLS_PLATFORM_TIME_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\
( !defined(MBEDTLS_PLATFORM_C) ||\
!defined(MBEDTLS_HAVE_TIME) )
#error "MBEDTLS_PLATFORM_TIME_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\
( !defined(MBEDTLS_PLATFORM_C) ||\
!defined(MBEDTLS_HAVE_TIME) )
#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\
( defined(MBEDTLS_PLATFORM_STD_TIME) ||\
defined(MBEDTLS_PLATFORM_TIME_ALT) )
#error "MBEDTLS_PLATFORM_TIME_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\
( defined(MBEDTLS_PLATFORM_STD_TIME) ||\
defined(MBEDTLS_PLATFORM_TIME_ALT) )
#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_FPRINTF_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_FPRINTF_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) &&\
( defined(MBEDTLS_PLATFORM_STD_FPRINTF) ||\
defined(MBEDTLS_PLATFORM_FPRINTF_ALT) )
#error "MBEDTLS_PLATFORM_FPRINTF_MACRO and MBEDTLS_PLATFORM_STD_FPRINTF/MBEDTLS_PLATFORM_FPRINTF_ALT cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) )
#error "MBEDTLS_PLATFORM_FREE_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\
defined(MBEDTLS_PLATFORM_STD_FREE)
#error "MBEDTLS_PLATFORM_FREE_MACRO and MBEDTLS_PLATFORM_STD_FREE cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && !defined(MBEDTLS_PLATFORM_CALLOC_MACRO)
#error "MBEDTLS_PLATFORM_CALLOC_MACRO must be defined if MBEDTLS_PLATFORM_FREE_MACRO is"
#endif
#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) )
#error "MBEDTLS_PLATFORM_CALLOC_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\
defined(MBEDTLS_PLATFORM_STD_CALLOC)
#error "MBEDTLS_PLATFORM_CALLOC_MACRO and MBEDTLS_PLATFORM_STD_CALLOC cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && !defined(MBEDTLS_PLATFORM_FREE_MACRO)
#error "MBEDTLS_PLATFORM_FREE_MACRO must be defined if MBEDTLS_PLATFORM_CALLOC_MACRO is"
#endif
#if defined(MBEDTLS_PLATFORM_MEMORY) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_MEMORY defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_PRINTF_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_PRINTF_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) &&\
( defined(MBEDTLS_PLATFORM_STD_PRINTF) ||\
defined(MBEDTLS_PLATFORM_PRINTF_ALT) )
#error "MBEDTLS_PLATFORM_PRINTF_MACRO and MBEDTLS_PLATFORM_STD_PRINTF/MBEDTLS_PLATFORM_PRINTF_ALT cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_SNPRINTF_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) &&\
( defined(MBEDTLS_PLATFORM_STD_SNPRINTF) ||\
defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) )
#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO and MBEDTLS_PLATFORM_STD_SNPRINTF/MBEDTLS_PLATFORM_SNPRINTF_ALT cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) &&\
!defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS)
#error "MBEDTLS_PLATFORM_STD_MEM_HDR defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_CALLOC) && !defined(MBEDTLS_PLATFORM_MEMORY)
#error "MBEDTLS_PLATFORM_STD_CALLOC defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_CALLOC) && !defined(MBEDTLS_PLATFORM_MEMORY)
#error "MBEDTLS_PLATFORM_STD_CALLOC defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_FREE) && !defined(MBEDTLS_PLATFORM_MEMORY)
#error "MBEDTLS_PLATFORM_STD_FREE defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_EXIT) &&\
!defined(MBEDTLS_PLATFORM_EXIT_ALT)
#error "MBEDTLS_PLATFORM_STD_EXIT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_TIME) &&\
( !defined(MBEDTLS_PLATFORM_TIME_ALT) ||\
!defined(MBEDTLS_HAVE_TIME) )
#error "MBEDTLS_PLATFORM_STD_TIME defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_FPRINTF) &&\
!defined(MBEDTLS_PLATFORM_FPRINTF_ALT)
#error "MBEDTLS_PLATFORM_STD_FPRINTF defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_PRINTF) &&\
!defined(MBEDTLS_PLATFORM_PRINTF_ALT)
#error "MBEDTLS_PLATFORM_STD_PRINTF defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_SNPRINTF) &&\
!defined(MBEDTLS_PLATFORM_SNPRINTF_ALT)
#error "MBEDTLS_PLATFORM_STD_SNPRINTF defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ENTROPY_NV_SEED) &&\
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_ENTROPY_C) )
#error "MBEDTLS_ENTROPY_NV_SEED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) &&\
!defined(MBEDTLS_ENTROPY_NV_SEED)
#error "MBEDTLS_PLATFORM_NV_SEED_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) &&\
!defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
#error "MBEDTLS_PLATFORM_STD_NV_SEED_READ defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) &&\
!defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
#error "MBEDTLS_PLATFORM_STD_NV_SEED_WRITE defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) &&\
( defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) ||\
defined(MBEDTLS_PLATFORM_NV_SEED_ALT) )
#error "MBEDTLS_PLATFORM_NV_SEED_READ_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_READ cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO) &&\
( defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) ||\
defined(MBEDTLS_PLATFORM_NV_SEED_ALT) )
#error "MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_WRITE cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_RSA_C) && ( \
( !defined(MBEDTLS_BIGNUM_C) && !defined(MBEDTLS_PK_ALT) ) || \
( !defined(MBEDTLS_OID_C) && !defined(MBEDTLS_IOT_SPECIFIC) ) )
#error "MBEDTLS_RSA_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_PKCS1_V21) && \
!defined(MBEDTLS_PKCS1_V15) )
#error "MBEDTLS_RSA_C defined, but none of the PKCS1 versions enabled"
#endif
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && \
( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_PKCS1_V21) )
#error "MBEDTLS_X509_RSASSA_PSS_SUPPORT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_PROTO_SSL3) && ( !defined(MBEDTLS_MD5_C) || \
!defined(MBEDTLS_SHA1_C) )
#error "MBEDTLS_SSL_PROTO_SSL3 defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1) && ( !defined(MBEDTLS_MD5_C) || \
!defined(MBEDTLS_SHA1_C) )
#error "MBEDTLS_SSL_PROTO_TLS1 defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_1) && ( !defined(MBEDTLS_MD5_C) || \
!defined(MBEDTLS_SHA1_C) )
#error "MBEDTLS_SSL_PROTO_TLS1_1 defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && ( !defined(MBEDTLS_SHA1_C) && \
!defined(MBEDTLS_SHA256_C) && !defined(MBEDTLS_SHA512_C) )
#error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_PROTO_DTLS) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
#error "MBEDTLS_SSL_PROTO_DTLS defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_CLI_C) && !defined(MBEDTLS_SSL_TLS_C)
#error "MBEDTLS_SSL_CLI_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_TLS_C) && ( !defined(MBEDTLS_CIPHER_C) || \
!defined(MBEDTLS_MD_C) )
#error "MBEDTLS_SSL_TLS_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_TLS_C)
#error "MBEDTLS_SSL_SRV_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_TLS_C) && (!defined(MBEDTLS_SSL_PROTO_SSL3) && \
!defined(MBEDTLS_SSL_PROTO_TLS1) && !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2))
#error "MBEDTLS_SSL_TLS_C defined, but no protocols are active"
#endif
#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \
defined(MBEDTLS_SSL_PROTO_TLS1_1) && !defined(MBEDTLS_SSL_PROTO_TLS1))
#error "Illegal protocol selection"
#endif
#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_TLS1) && \
defined(MBEDTLS_SSL_PROTO_TLS1_2) && !defined(MBEDTLS_SSL_PROTO_TLS1_1))
#error "Illegal protocol selection"
#endif
#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \
defined(MBEDTLS_SSL_PROTO_TLS1_2) && (!defined(MBEDTLS_SSL_PROTO_TLS1) || \
!defined(MBEDTLS_SSL_PROTO_TLS1_1)))
#error "Illegal protocol selection"
#endif
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && !defined(MBEDTLS_SSL_PROTO_DTLS)
#error "MBEDTLS_SSL_DTLS_HELLO_VERIFY defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && \
!defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
#error "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \
( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) )
#error "MBEDTLS_SSL_DTLS_ANTI_REPLAY defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) && \
( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) )
#error "MBEDTLS_SSL_DTLS_BADMAC_LIMIT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \
!defined(MBEDTLS_SSL_PROTO_TLS1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
#error "MBEDTLS_SSL_ENCRYPT_THEN_MAC defined, but not all prerequsites"
#endif
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) && \
!defined(MBEDTLS_SSL_PROTO_TLS1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
#error "MBEDTLS_SSL_EXTENDED_MASTER_SECRET defined, but not all prerequsites"
#endif
#if defined(MBEDTLS_SSL_TICKET_C) && !defined(MBEDTLS_CIPHER_C)
#error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) && \
!defined(MBEDTLS_SSL_PROTO_SSL3) && !defined(MBEDTLS_SSL_PROTO_TLS1)
#error "MBEDTLS_SSL_CBC_RECORD_SPLITTING defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && \
!defined(MBEDTLS_X509_CRT_PARSE_C)
#error "MBEDTLS_SSL_SERVER_NAME_INDICATION defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_THREADING_PTHREAD)
#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL)
#error "MBEDTLS_THREADING_PTHREAD defined, but not all prerequisites"
#endif
#define MBEDTLS_THREADING_IMPL
#endif
#if defined(MBEDTLS_THREADING_ALT)
#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL)
#error "MBEDTLS_THREADING_ALT defined, but not all prerequisites"
#endif
#define MBEDTLS_THREADING_IMPL
#endif
#if defined(MBEDTLS_THREADING_C) && !defined(MBEDTLS_THREADING_IMPL)
#error "MBEDTLS_THREADING_C defined, single threading implementation required"
#endif
#undef MBEDTLS_THREADING_IMPL
#if defined(MBEDTLS_VERSION_FEATURES) && !defined(MBEDTLS_VERSION_C)
#error "MBEDTLS_VERSION_FEATURES defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_USE_C) && ( \
( !defined(MBEDTLS_BIGNUM_C) && !defined(MBEDTLS_PK_ALT)) || \
(!defined(MBEDTLS_OID_C) && !defined(MBEDTLS_IOT_SPECIFIC)) || \
!defined(MBEDTLS_ASN1_PARSE_C) || !defined(MBEDTLS_PK_PARSE_C) )
#error "MBEDTLS_X509_USE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_CREATE_C) && ( !defined(MBEDTLS_BIGNUM_C) || \
!defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_WRITE_C) || \
!defined(MBEDTLS_PK_WRITE_C) )
#error "MBEDTLS_X509_CREATE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_CRT_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) )
#error "MBEDTLS_X509_CRT_PARSE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_CRL_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) )
#error "MBEDTLS_X509_CRL_PARSE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_CSR_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) )
#error "MBEDTLS_X509_CSR_PARSE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_CRT_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) )
#error "MBEDTLS_X509_CRT_WRITE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_CSR_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) )
#error "MBEDTLS_X509_CSR_WRITE_C defined, but not all prerequisites"
#endif
/*
* Avoid warning from -pedantic. This is a convenient place for this
* workaround since this is included by every single file before the
* #if defined(MBEDTLS_xxx_C) that results in emtpy translation units.
*/
typedef int mbedtls_iso_c_forbids_empty_translation_units;
#endif /* MBEDTLS_CHECK_CONFIG_H */

View file

@ -0,0 +1,628 @@
/**
* \file check_config.h
*
* \brief Consistency checks for configuration options
*
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* It is recommended to include this file from your config.h
* in order to catch dependency issues early.
*/
#ifndef MBEDTLS_CHECK_CONFIG_H
#define MBEDTLS_CHECK_CONFIG_H
/*
* We assume CHAR_BIT is 8 in many places. In practice, this is true on our
* target platforms, so not an issue, but let's just be extra sure.
*/
#include <limits.h>
#if CHAR_BIT != 8
#error "mbed TLS requires a platform with 8-bit chars"
#endif
#if defined(_WIN32)
#if !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_C is required on Windows"
#endif
/* Fix the config here. Not convenient to put an #ifdef _WIN32 in config.h as
* it would confuse config.pl. */
#if !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && \
!defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO)
#define MBEDTLS_PLATFORM_SNPRINTF_ALT
#endif
#endif /* _WIN32 */
#if defined(TARGET_LIKE_MBED) && \
( defined(MBEDTLS_NET_C) || defined(MBEDTLS_TIMING_C) )
#error "The NET and TIMING modules are not available for mbed OS - please use the network and timing functions provided by mbed OS"
#endif
#if defined(MBEDTLS_DEPRECATED_WARNING) && \
!defined(__GNUC__) && !defined(__clang__)
#error "MBEDTLS_DEPRECATED_WARNING only works with GCC and Clang"
#endif
#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_HAVE_TIME)
#error "MBEDTLS_HAVE_TIME_DATE without MBEDTLS_HAVE_TIME does not make sense"
#endif
#if defined(MBEDTLS_AESNI_C) && !defined(MBEDTLS_HAVE_ASM)
#error "MBEDTLS_AESNI_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_AES_C)
#error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_DHM_C) && !defined(MBEDTLS_BIGNUM_C)
#error "MBEDTLS_DHM_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_CMAC_C) && \
!defined(MBEDTLS_AES_C) && !defined(MBEDTLS_DES_C)
#error "MBEDTLS_CMAC_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECDH_C) && !defined(MBEDTLS_ECP_C)
#error "MBEDTLS_ECDH_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECDSA_C) && \
( !defined(MBEDTLS_ECP_C) || \
!defined(MBEDTLS_ASN1_PARSE_C) || \
!defined(MBEDTLS_ASN1_WRITE_C) )
#error "MBEDTLS_ECDSA_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECJPAKE_C) && \
( !defined(MBEDTLS_ECP_C) || !defined(MBEDTLS_MD_C) )
#error "MBEDTLS_ECJPAKE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C)
#error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || ( \
!defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) && \
!defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) ) )
#error "MBEDTLS_ECP_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ENTROPY_C) && (!defined(MBEDTLS_SHA512_C) && \
!defined(MBEDTLS_SHA256_C))
#error "MBEDTLS_ENTROPY_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_SHA512_C) && \
defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 64)
#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high"
#endif
#if defined(MBEDTLS_ENTROPY_C) && \
( !defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_ENTROPY_FORCE_SHA256) ) \
&& defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 32)
#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high"
#endif
#if defined(MBEDTLS_ENTROPY_C) && \
defined(MBEDTLS_ENTROPY_FORCE_SHA256) && !defined(MBEDTLS_SHA256_C)
#error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \
( !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) )
#error "MBEDTLS_TEST_NULL_ENTROPY defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \
( defined(MBEDTLS_ENTROPY_NV_SEED) || defined(MBEDTLS_ENTROPY_HARDWARE_ALT) || \
defined(MBEDTLS_HAVEGE_C) )
#error "MBEDTLS_TEST_NULL_ENTROPY defined, but entropy sources too"
#endif
#if defined(MBEDTLS_GCM_C) && ( \
!defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) )
#error "MBEDTLS_GCM_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_HAVEGE_C) && !defined(MBEDTLS_TIMING_C)
#error "MBEDTLS_HAVEGE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_HMAC_DRBG_C) && !defined(MBEDTLS_MD_C)
#error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) && !defined(MBEDTLS_DHM_C)
#error "MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) && \
!defined(MBEDTLS_ECDH_C)
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
( !defined(MBEDTLS_DHM_C) || !defined(MBEDTLS_RSA_C) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) )
#error "MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_RSA_C) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) )
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDSA_C) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) && \
( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \
!defined(MBEDTLS_PKCS1_V15) )
#error "MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \
!defined(MBEDTLS_PKCS1_V15) )
#error "MBEDTLS_KEY_EXCHANGE_RSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
( !defined(MBEDTLS_ECJPAKE_C) || !defined(MBEDTLS_SHA256_C) || \
!defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) )
#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) )
#error "MBEDTLS_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PADLOCK_C) && !defined(MBEDTLS_HAVE_ASM)
#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PEM_PARSE_C) && !defined(MBEDTLS_BASE64_C)
#error "MBEDTLS_PEM_PARSE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PEM_WRITE_C) && !defined(MBEDTLS_BASE64_C)
#error "MBEDTLS_PEM_WRITE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PK_C) && \
( !defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_ECP_C) )
#error "MBEDTLS_PK_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_PK_C)
#error "MBEDTLS_PK_PARSE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PK_WRITE_C) && !defined(MBEDTLS_PK_C)
#error "MBEDTLS_PK_WRITE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PKCS11_C) && !defined(MBEDTLS_PK_C)
#error "MBEDTLS_PKCS11_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_EXIT_ALT) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_EXIT_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_EXIT_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) &&\
( defined(MBEDTLS_PLATFORM_STD_EXIT) ||\
defined(MBEDTLS_PLATFORM_EXIT_ALT) )
#error "MBEDTLS_PLATFORM_EXIT_MACRO and MBEDTLS_PLATFORM_STD_EXIT/MBEDTLS_PLATFORM_EXIT_ALT cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_TIME_ALT) &&\
( !defined(MBEDTLS_PLATFORM_C) ||\
!defined(MBEDTLS_HAVE_TIME) )
#error "MBEDTLS_PLATFORM_TIME_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\
( !defined(MBEDTLS_PLATFORM_C) ||\
!defined(MBEDTLS_HAVE_TIME) )
#error "MBEDTLS_PLATFORM_TIME_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\
( !defined(MBEDTLS_PLATFORM_C) ||\
!defined(MBEDTLS_HAVE_TIME) )
#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\
( defined(MBEDTLS_PLATFORM_STD_TIME) ||\
defined(MBEDTLS_PLATFORM_TIME_ALT) )
#error "MBEDTLS_PLATFORM_TIME_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\
( defined(MBEDTLS_PLATFORM_STD_TIME) ||\
defined(MBEDTLS_PLATFORM_TIME_ALT) )
#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_FPRINTF_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_FPRINTF_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) &&\
( defined(MBEDTLS_PLATFORM_STD_FPRINTF) ||\
defined(MBEDTLS_PLATFORM_FPRINTF_ALT) )
#error "MBEDTLS_PLATFORM_FPRINTF_MACRO and MBEDTLS_PLATFORM_STD_FPRINTF/MBEDTLS_PLATFORM_FPRINTF_ALT cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) )
#error "MBEDTLS_PLATFORM_FREE_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\
defined(MBEDTLS_PLATFORM_STD_FREE)
#error "MBEDTLS_PLATFORM_FREE_MACRO and MBEDTLS_PLATFORM_STD_FREE cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && !defined(MBEDTLS_PLATFORM_CALLOC_MACRO)
#error "MBEDTLS_PLATFORM_CALLOC_MACRO must be defined if MBEDTLS_PLATFORM_FREE_MACRO is"
#endif
#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) )
#error "MBEDTLS_PLATFORM_CALLOC_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\
defined(MBEDTLS_PLATFORM_STD_CALLOC)
#error "MBEDTLS_PLATFORM_CALLOC_MACRO and MBEDTLS_PLATFORM_STD_CALLOC cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && !defined(MBEDTLS_PLATFORM_FREE_MACRO)
#error "MBEDTLS_PLATFORM_FREE_MACRO must be defined if MBEDTLS_PLATFORM_CALLOC_MACRO is"
#endif
#if defined(MBEDTLS_PLATFORM_MEMORY) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_MEMORY defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_PRINTF_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_PRINTF_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) &&\
( defined(MBEDTLS_PLATFORM_STD_PRINTF) ||\
defined(MBEDTLS_PLATFORM_PRINTF_ALT) )
#error "MBEDTLS_PLATFORM_PRINTF_MACRO and MBEDTLS_PLATFORM_STD_PRINTF/MBEDTLS_PLATFORM_PRINTF_ALT cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_SNPRINTF_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) &&\
( defined(MBEDTLS_PLATFORM_STD_SNPRINTF) ||\
defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) )
#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO and MBEDTLS_PLATFORM_STD_SNPRINTF/MBEDTLS_PLATFORM_SNPRINTF_ALT cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) &&\
!defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS)
#error "MBEDTLS_PLATFORM_STD_MEM_HDR defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_CALLOC) && !defined(MBEDTLS_PLATFORM_MEMORY)
#error "MBEDTLS_PLATFORM_STD_CALLOC defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_CALLOC) && !defined(MBEDTLS_PLATFORM_MEMORY)
#error "MBEDTLS_PLATFORM_STD_CALLOC defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_FREE) && !defined(MBEDTLS_PLATFORM_MEMORY)
#error "MBEDTLS_PLATFORM_STD_FREE defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_EXIT) &&\
!defined(MBEDTLS_PLATFORM_EXIT_ALT)
#error "MBEDTLS_PLATFORM_STD_EXIT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_TIME) &&\
( !defined(MBEDTLS_PLATFORM_TIME_ALT) ||\
!defined(MBEDTLS_HAVE_TIME) )
#error "MBEDTLS_PLATFORM_STD_TIME defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_FPRINTF) &&\
!defined(MBEDTLS_PLATFORM_FPRINTF_ALT)
#error "MBEDTLS_PLATFORM_STD_FPRINTF defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_PRINTF) &&\
!defined(MBEDTLS_PLATFORM_PRINTF_ALT)
#error "MBEDTLS_PLATFORM_STD_PRINTF defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_SNPRINTF) &&\
!defined(MBEDTLS_PLATFORM_SNPRINTF_ALT)
#error "MBEDTLS_PLATFORM_STD_SNPRINTF defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ENTROPY_NV_SEED) &&\
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_ENTROPY_C) )
#error "MBEDTLS_ENTROPY_NV_SEED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) &&\
!defined(MBEDTLS_ENTROPY_NV_SEED)
#error "MBEDTLS_PLATFORM_NV_SEED_ALT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) &&\
!defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
#error "MBEDTLS_PLATFORM_STD_NV_SEED_READ defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) &&\
!defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
#error "MBEDTLS_PLATFORM_STD_NV_SEED_WRITE defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) &&\
( defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) ||\
defined(MBEDTLS_PLATFORM_NV_SEED_ALT) )
#error "MBEDTLS_PLATFORM_NV_SEED_READ_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_READ cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO) &&\
( defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) ||\
defined(MBEDTLS_PLATFORM_NV_SEED_ALT) )
#error "MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_WRITE cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) || \
!defined(MBEDTLS_OID_C) )
#error "MBEDTLS_RSA_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_PKCS1_V21) && \
!defined(MBEDTLS_PKCS1_V15) )
#error "MBEDTLS_RSA_C defined, but none of the PKCS1 versions enabled"
#endif
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && \
( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_PKCS1_V21) )
#error "MBEDTLS_X509_RSASSA_PSS_SUPPORT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_PROTO_SSL3) && ( !defined(MBEDTLS_MD5_C) || \
!defined(MBEDTLS_SHA1_C) )
#error "MBEDTLS_SSL_PROTO_SSL3 defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1) && ( !defined(MBEDTLS_MD5_C) || \
!defined(MBEDTLS_SHA1_C) )
#error "MBEDTLS_SSL_PROTO_TLS1 defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_1) && ( !defined(MBEDTLS_MD5_C) || \
!defined(MBEDTLS_SHA1_C) )
#error "MBEDTLS_SSL_PROTO_TLS1_1 defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && ( !defined(MBEDTLS_SHA1_C) && \
!defined(MBEDTLS_SHA256_C) && !defined(MBEDTLS_SHA512_C) )
#error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_PROTO_DTLS) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
#error "MBEDTLS_SSL_PROTO_DTLS defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_CLI_C) && !defined(MBEDTLS_SSL_TLS_C)
#error "MBEDTLS_SSL_CLI_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_TLS_C) && ( !defined(MBEDTLS_CIPHER_C) || \
!defined(MBEDTLS_MD_C) )
#error "MBEDTLS_SSL_TLS_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_TLS_C)
#error "MBEDTLS_SSL_SRV_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_TLS_C) && (!defined(MBEDTLS_SSL_PROTO_SSL3) && \
!defined(MBEDTLS_SSL_PROTO_TLS1) && !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2))
#error "MBEDTLS_SSL_TLS_C defined, but no protocols are active"
#endif
#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \
defined(MBEDTLS_SSL_PROTO_TLS1_1) && !defined(MBEDTLS_SSL_PROTO_TLS1))
#error "Illegal protocol selection"
#endif
#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_TLS1) && \
defined(MBEDTLS_SSL_PROTO_TLS1_2) && !defined(MBEDTLS_SSL_PROTO_TLS1_1))
#error "Illegal protocol selection"
#endif
#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \
defined(MBEDTLS_SSL_PROTO_TLS1_2) && (!defined(MBEDTLS_SSL_PROTO_TLS1) || \
!defined(MBEDTLS_SSL_PROTO_TLS1_1)))
#error "Illegal protocol selection"
#endif
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && !defined(MBEDTLS_SSL_PROTO_DTLS)
#error "MBEDTLS_SSL_DTLS_HELLO_VERIFY defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && \
!defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
#error "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \
( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) )
#error "MBEDTLS_SSL_DTLS_ANTI_REPLAY defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) && \
( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) )
#error "MBEDTLS_SSL_DTLS_BADMAC_LIMIT defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \
!defined(MBEDTLS_SSL_PROTO_TLS1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
#error "MBEDTLS_SSL_ENCRYPT_THEN_MAC defined, but not all prerequsites"
#endif
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) && \
!defined(MBEDTLS_SSL_PROTO_TLS1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
#error "MBEDTLS_SSL_EXTENDED_MASTER_SECRET defined, but not all prerequsites"
#endif
#if defined(MBEDTLS_SSL_TICKET_C) && !defined(MBEDTLS_CIPHER_C)
#error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) && \
!defined(MBEDTLS_SSL_PROTO_SSL3) && !defined(MBEDTLS_SSL_PROTO_TLS1)
#error "MBEDTLS_SSL_CBC_RECORD_SPLITTING defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && \
!defined(MBEDTLS_X509_CRT_PARSE_C)
#error "MBEDTLS_SSL_SERVER_NAME_INDICATION defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_THREADING_PTHREAD)
#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL)
#error "MBEDTLS_THREADING_PTHREAD defined, but not all prerequisites"
#endif
#define MBEDTLS_THREADING_IMPL
#endif
#if defined(MBEDTLS_THREADING_ALT)
#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL)
#error "MBEDTLS_THREADING_ALT defined, but not all prerequisites"
#endif
#define MBEDTLS_THREADING_IMPL
#endif
#if defined(MBEDTLS_THREADING_C) && !defined(MBEDTLS_THREADING_IMPL)
#error "MBEDTLS_THREADING_C defined, single threading implementation required"
#endif
#undef MBEDTLS_THREADING_IMPL
#if defined(MBEDTLS_VERSION_FEATURES) && !defined(MBEDTLS_VERSION_C)
#error "MBEDTLS_VERSION_FEATURES defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_USE_C) && ( !defined(MBEDTLS_BIGNUM_C) || \
!defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_PARSE_C) || \
!defined(MBEDTLS_PK_PARSE_C) )
#error "MBEDTLS_X509_USE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_CREATE_C) && ( !defined(MBEDTLS_BIGNUM_C) || \
!defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_WRITE_C) || \
!defined(MBEDTLS_PK_WRITE_C) )
#error "MBEDTLS_X509_CREATE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_CRT_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) )
#error "MBEDTLS_X509_CRT_PARSE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_CRL_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) )
#error "MBEDTLS_X509_CRL_PARSE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_CSR_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) )
#error "MBEDTLS_X509_CSR_PARSE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_CRT_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) )
#error "MBEDTLS_X509_CRT_WRITE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_X509_CSR_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) )
#error "MBEDTLS_X509_CSR_WRITE_C defined, but not all prerequisites"
#endif
/*
* Avoid warning from -pedantic. This is a convenient place for this
* workaround since this is included by every single file before the
* #if defined(MBEDTLS_xxx_C) that results in emtpy translation units.
*/
typedef int mbedtls_iso_c_forbids_empty_translation_units;
#endif /* MBEDTLS_CHECK_CONFIG_H */

View file

@ -0,0 +1,709 @@
/**
* \file cipher.h
*
* \brief Generic cipher wrapper.
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_CIPHER_H
#define MBEDTLS_CIPHER_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C)
#define MBEDTLS_CIPHER_MODE_AEAD
#endif
#if defined(MBEDTLS_CIPHER_MODE_CBC)
#define MBEDTLS_CIPHER_MODE_WITH_PADDING
#endif
#if defined(MBEDTLS_ARC4_C)
#define MBEDTLS_CIPHER_MODE_STREAM
#endif
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
#endif
#define MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE -0x6080 /**< The selected feature is not available. */
#define MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA -0x6100 /**< Bad input parameters to function. */
#define MBEDTLS_ERR_CIPHER_ALLOC_FAILED -0x6180 /**< Failed to allocate memory. */
#define MBEDTLS_ERR_CIPHER_INVALID_PADDING -0x6200 /**< Input data contains invalid padding and is rejected. */
#define MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED -0x6280 /**< Decryption of block requires a full block. */
#define MBEDTLS_ERR_CIPHER_AUTH_FAILED -0x6300 /**< Authentication failed (for AEAD modes). */
#define MBEDTLS_ERR_CIPHER_INVALID_CONTEXT -0x6380 /**< The context is invalid, eg because it was free()ed. */
#define MBEDTLS_CIPHER_VARIABLE_IV_LEN 0x01 /**< Cipher accepts IVs of variable length */
#define MBEDTLS_CIPHER_VARIABLE_KEY_LEN 0x02 /**< Cipher accepts keys of variable length */
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
MBEDTLS_CIPHER_ID_NONE = 0,
MBEDTLS_CIPHER_ID_NULL,
MBEDTLS_CIPHER_ID_AES,
MBEDTLS_CIPHER_ID_DES,
MBEDTLS_CIPHER_ID_3DES,
MBEDTLS_CIPHER_ID_CAMELLIA,
MBEDTLS_CIPHER_ID_BLOWFISH,
MBEDTLS_CIPHER_ID_ARC4,
} mbedtls_cipher_id_t;
typedef enum {
MBEDTLS_CIPHER_NONE = 0,
MBEDTLS_CIPHER_NULL,
MBEDTLS_CIPHER_AES_128_ECB,
MBEDTLS_CIPHER_AES_192_ECB,
MBEDTLS_CIPHER_AES_256_ECB,
MBEDTLS_CIPHER_AES_128_CBC,
MBEDTLS_CIPHER_AES_192_CBC,
MBEDTLS_CIPHER_AES_256_CBC,
MBEDTLS_CIPHER_AES_128_CFB128,
MBEDTLS_CIPHER_AES_192_CFB128,
MBEDTLS_CIPHER_AES_256_CFB128,
MBEDTLS_CIPHER_AES_128_CTR,
MBEDTLS_CIPHER_AES_192_CTR,
MBEDTLS_CIPHER_AES_256_CTR,
MBEDTLS_CIPHER_AES_128_GCM,
MBEDTLS_CIPHER_AES_192_GCM,
MBEDTLS_CIPHER_AES_256_GCM,
MBEDTLS_CIPHER_CAMELLIA_128_ECB,
MBEDTLS_CIPHER_CAMELLIA_192_ECB,
MBEDTLS_CIPHER_CAMELLIA_256_ECB,
MBEDTLS_CIPHER_CAMELLIA_128_CBC,
MBEDTLS_CIPHER_CAMELLIA_192_CBC,
MBEDTLS_CIPHER_CAMELLIA_256_CBC,
MBEDTLS_CIPHER_CAMELLIA_128_CFB128,
MBEDTLS_CIPHER_CAMELLIA_192_CFB128,
MBEDTLS_CIPHER_CAMELLIA_256_CFB128,
MBEDTLS_CIPHER_CAMELLIA_128_CTR,
MBEDTLS_CIPHER_CAMELLIA_192_CTR,
MBEDTLS_CIPHER_CAMELLIA_256_CTR,
MBEDTLS_CIPHER_CAMELLIA_128_GCM,
MBEDTLS_CIPHER_CAMELLIA_192_GCM,
MBEDTLS_CIPHER_CAMELLIA_256_GCM,
MBEDTLS_CIPHER_DES_ECB,
MBEDTLS_CIPHER_DES_CBC,
MBEDTLS_CIPHER_DES_EDE_ECB,
MBEDTLS_CIPHER_DES_EDE_CBC,
MBEDTLS_CIPHER_DES_EDE3_ECB,
MBEDTLS_CIPHER_DES_EDE3_CBC,
MBEDTLS_CIPHER_BLOWFISH_ECB,
MBEDTLS_CIPHER_BLOWFISH_CBC,
MBEDTLS_CIPHER_BLOWFISH_CFB64,
MBEDTLS_CIPHER_BLOWFISH_CTR,
MBEDTLS_CIPHER_ARC4_128,
MBEDTLS_CIPHER_AES_128_CCM,
MBEDTLS_CIPHER_AES_192_CCM,
MBEDTLS_CIPHER_AES_256_CCM,
MBEDTLS_CIPHER_CAMELLIA_128_CCM,
MBEDTLS_CIPHER_CAMELLIA_192_CCM,
MBEDTLS_CIPHER_CAMELLIA_256_CCM,
} mbedtls_cipher_type_t;
typedef enum {
MBEDTLS_MODE_NONE = 0,
MBEDTLS_MODE_ECB,
MBEDTLS_MODE_CBC,
MBEDTLS_MODE_CFB,
MBEDTLS_MODE_OFB, /* Unused! */
MBEDTLS_MODE_CTR,
MBEDTLS_MODE_GCM,
MBEDTLS_MODE_STREAM,
MBEDTLS_MODE_CCM,
} mbedtls_cipher_mode_t;
typedef enum {
MBEDTLS_PADDING_PKCS7 = 0, /**< PKCS7 padding (default) */
MBEDTLS_PADDING_ONE_AND_ZEROS, /**< ISO/IEC 7816-4 padding */
MBEDTLS_PADDING_ZEROS_AND_LEN, /**< ANSI X.923 padding */
MBEDTLS_PADDING_ZEROS, /**< zero padding (not reversible!) */
MBEDTLS_PADDING_NONE, /**< never pad (full blocks only) */
} mbedtls_cipher_padding_t;
typedef enum {
MBEDTLS_OPERATION_NONE = -1,
MBEDTLS_DECRYPT = 0,
MBEDTLS_ENCRYPT,
} mbedtls_operation_t;
enum {
/** Undefined key length */
MBEDTLS_KEY_LENGTH_NONE = 0,
/** Key length, in bits (including parity), for DES keys */
MBEDTLS_KEY_LENGTH_DES = 64,
/** Key length, in bits (including parity), for DES in two key EDE */
MBEDTLS_KEY_LENGTH_DES_EDE = 128,
/** Key length, in bits (including parity), for DES in three-key EDE */
MBEDTLS_KEY_LENGTH_DES_EDE3 = 192,
};
/** Maximum length of any IV, in bytes */
#define MBEDTLS_MAX_IV_LENGTH 16
/** Maximum block size of any cipher, in bytes */
#define MBEDTLS_MAX_BLOCK_LENGTH 16
/**
* Base cipher information (opaque struct).
*/
typedef struct mbedtls_cipher_base_t mbedtls_cipher_base_t;
/**
* CMAC context (opaque struct).
*/
typedef struct mbedtls_cmac_context_t mbedtls_cmac_context_t;
/**
* Cipher information. Allows cipher functions to be called in a generic way.
*/
typedef struct {
/** Full cipher identifier (e.g. MBEDTLS_CIPHER_AES_256_CBC) */
mbedtls_cipher_type_t type;
/** Cipher mode (e.g. MBEDTLS_MODE_CBC) */
mbedtls_cipher_mode_t mode;
/** Cipher key length, in bits (default length for variable sized ciphers)
* (Includes parity bits for ciphers like DES) */
unsigned int key_bitlen;
/** Name of the cipher */
const char * name;
/** IV/NONCE size, in bytes.
* For cipher that accept many sizes: recommended size */
unsigned int iv_size;
/** Flags for variable IV size, variable key size, etc. */
int flags;
/** block size, in bytes */
unsigned int block_size;
/** Base cipher information and functions */
const mbedtls_cipher_base_t *base;
} mbedtls_cipher_info_t;
/**
* Generic cipher context.
*/
typedef struct {
/** Information about the associated cipher */
const mbedtls_cipher_info_t *cipher_info;
/** Key length to use */
int key_bitlen;
/** Operation that the context's key has been initialised for */
mbedtls_operation_t operation;
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
/** Padding functions to use, if relevant for cipher mode */
void (*add_padding)( unsigned char *output, size_t olen, size_t data_len );
int (*get_padding)( unsigned char *input, size_t ilen, size_t *data_len );
#endif
/** Buffer for data that hasn't been encrypted yet */
unsigned char unprocessed_data[MBEDTLS_MAX_BLOCK_LENGTH];
/** Number of bytes that still need processing */
size_t unprocessed_len;
/** Current IV or NONCE_COUNTER for CTR-mode */
unsigned char iv[MBEDTLS_MAX_IV_LENGTH];
/** IV size in bytes (for ciphers with variable-length IVs) */
size_t iv_size;
/** Cipher-specific context */
void *cipher_ctx;
#if defined(MBEDTLS_CMAC_C)
/** CMAC Specific context */
mbedtls_cmac_context_t *cmac_ctx;
#endif
} mbedtls_cipher_context_t;
/**
* \brief Returns the list of ciphers supported by the generic cipher module.
*
* \return a statically allocated array of ciphers, the last entry
* is 0.
*/
const int *mbedtls_cipher_list( void );
/**
* \brief Returns the cipher information structure associated
* with the given cipher name.
*
* \param cipher_name Name of the cipher to search for.
*
* \return the cipher information structure associated with the
* given cipher_name, or NULL if not found.
*/
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name );
/**
* \brief Returns the cipher information structure associated
* with the given cipher type.
*
* \param cipher_type Type of the cipher to search for.
*
* \return the cipher information structure associated with the
* given cipher_type, or NULL if not found.
*/
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type );
/**
* \brief Returns the cipher information structure associated
* with the given cipher id, key size and mode.
*
* \param cipher_id Id of the cipher to search for
* (e.g. MBEDTLS_CIPHER_ID_AES)
* \param key_bitlen Length of the key in bits
* \param mode Cipher mode (e.g. MBEDTLS_MODE_CBC)
*
* \return the cipher information structure associated with the
* given cipher_type, or NULL if not found.
*/
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id,
int key_bitlen,
const mbedtls_cipher_mode_t mode );
/**
* \brief Initialize a cipher_context (as NONE)
*/
void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx );
/**
* \brief Free and clear the cipher-specific context of ctx.
* Freeing ctx itself remains the responsibility of the
* caller.
*/
void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx );
/**
* \brief Initialises and fills the cipher context structure with
* the appropriate values.
*
* \note Currently also clears structure. In future versions you
* will be required to call mbedtls_cipher_init() on the structure
* first.
*
* \param ctx context to initialise. May not be NULL.
* \param cipher_info cipher to use.
*
* \return 0 on success,
* MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on parameter failure,
* MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the
* cipher-specific context failed.
*/
int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info );
/**
* \brief Returns the block size of the given cipher.
*
* \param ctx cipher's context. Must have been initialised.
*
* \return size of the cipher's blocks, or 0 if ctx has not been
* initialised.
*/
static inline unsigned int mbedtls_cipher_get_block_size( const mbedtls_cipher_context_t *ctx )
{
if( NULL == ctx || NULL == ctx->cipher_info )
return 0;
return ctx->cipher_info->block_size;
}
/**
* \brief Returns the mode of operation for the cipher.
* (e.g. MBEDTLS_MODE_CBC)
*
* \param ctx cipher's context. Must have been initialised.
*
* \return mode of operation, or MBEDTLS_MODE_NONE if ctx
* has not been initialised.
*/
static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode( const mbedtls_cipher_context_t *ctx )
{
if( NULL == ctx || NULL == ctx->cipher_info )
return MBEDTLS_MODE_NONE;
return ctx->cipher_info->mode;
}
/**
* \brief Returns the size of the cipher's IV/NONCE in bytes.
*
* \param ctx cipher's context. Must have been initialised.
*
* \return If IV has not been set yet: (recommended) IV size
* (0 for ciphers not using IV/NONCE).
* If IV has already been set: actual size.
*/
static inline int mbedtls_cipher_get_iv_size( const mbedtls_cipher_context_t *ctx )
{
if( NULL == ctx || NULL == ctx->cipher_info )
return 0;
if( ctx->iv_size != 0 )
return (int) ctx->iv_size;
return (int) ctx->cipher_info->iv_size;
}
/**
* \brief Returns the type of the given cipher.
*
* \param ctx cipher's context. Must have been initialised.
*
* \return type of the cipher, or MBEDTLS_CIPHER_NONE if ctx has
* not been initialised.
*/
static inline mbedtls_cipher_type_t mbedtls_cipher_get_type( const mbedtls_cipher_context_t *ctx )
{
if( NULL == ctx || NULL == ctx->cipher_info )
return MBEDTLS_CIPHER_NONE;
return ctx->cipher_info->type;
}
/**
* \brief Returns the name of the given cipher, as a string.
*
* \param ctx cipher's context. Must have been initialised.
*
* \return name of the cipher, or NULL if ctx was not initialised.
*/
static inline const char *mbedtls_cipher_get_name( const mbedtls_cipher_context_t *ctx )
{
if( NULL == ctx || NULL == ctx->cipher_info )
return 0;
return ctx->cipher_info->name;
}
/**
* \brief Returns the key length of the cipher.
*
* \param ctx cipher's context. Must have been initialised.
*
* \return cipher's key length, in bits, or
* MBEDTLS_KEY_LENGTH_NONE if ctx has not been
* initialised.
*/
static inline int mbedtls_cipher_get_key_bitlen( const mbedtls_cipher_context_t *ctx )
{
if( NULL == ctx || NULL == ctx->cipher_info )
return MBEDTLS_KEY_LENGTH_NONE;
return (int) ctx->cipher_info->key_bitlen;
}
/**
* \brief Returns the operation of the given cipher.
*
* \param ctx cipher's context. Must have been initialised.
*
* \return operation (MBEDTLS_ENCRYPT or MBEDTLS_DECRYPT),
* or MBEDTLS_OPERATION_NONE if ctx has not been
* initialised.
*/
static inline mbedtls_operation_t mbedtls_cipher_get_operation( const mbedtls_cipher_context_t *ctx )
{
if( NULL == ctx || NULL == ctx->cipher_info )
return MBEDTLS_OPERATION_NONE;
return ctx->operation;
}
/**
* \brief Set the key to use with the given context.
*
* \param ctx generic cipher context. May not be NULL. Must have been
* initialised using cipher_context_from_type or
* cipher_context_from_string.
* \param key The key to use.
* \param key_bitlen key length to use, in bits.
* \param operation Operation that the key will be used for, either
* MBEDTLS_ENCRYPT or MBEDTLS_DECRYPT.
*
* \returns 0 on success, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if
* parameter verification fails or a cipher specific
* error code.
*/
int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *key,
int key_bitlen, const mbedtls_operation_t operation );
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
/**
* \brief Set padding mode, for cipher modes that use padding.
* (Default: PKCS7 padding.)
*
* \param ctx generic cipher context
* \param mode padding mode
*
* \returns 0 on success, MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE
* if selected padding mode is not supported, or
* MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if the cipher mode
* does not support padding.
*/
int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, mbedtls_cipher_padding_t mode );
#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
/**
* \brief Set the initialization vector (IV) or nonce
*
* \param ctx generic cipher context
* \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers)
* \param iv_len IV length for ciphers with variable-size IV;
* discarded by ciphers with fixed-size IV.
*
* \returns 0 on success, or MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA
*
* \note Some ciphers don't use IVs nor NONCE. For these
* ciphers, this function has no effect.
*/
int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
const unsigned char *iv, size_t iv_len );
/**
* \brief Finish preparation of the given context
*
* \param ctx generic cipher context
*
* \returns 0 on success, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA
* if parameter verification fails.
*/
int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx );
#if defined(MBEDTLS_GCM_C)
/**
* \brief Add additional data (for AEAD ciphers).
* Currently only supported with GCM.
* Must be called exactly once, after mbedtls_cipher_reset().
*
* \param ctx generic cipher context
* \param ad Additional data to use.
* \param ad_len Length of ad.
*
* \return 0 on success, or a specific error code.
*/
int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
const unsigned char *ad, size_t ad_len );
#endif /* MBEDTLS_GCM_C */
/**
* \brief Generic cipher update function. Encrypts/decrypts
* using the given cipher context. Writes as many block
* size'd blocks of data as possible to output. Any data
* that cannot be written immediately will either be added
* to the next block, or flushed when cipher_final is
* called.
* Exception: for MBEDTLS_MODE_ECB, expects single block
* in size (e.g. 16 bytes for AES)
*
* \param ctx generic cipher context
* \param input buffer holding the input data
* \param ilen length of the input data
* \param output buffer for the output data. Should be able to hold at
* least ilen + block_size. Cannot be the same buffer as
* input!
* \param olen length of the output data, will be filled with the
* actual number of bytes written.
*
* \returns 0 on success, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if
* parameter verification fails,
* MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE on an
* unsupported mode for a cipher or a cipher specific
* error code.
*
* \note If the underlying cipher is GCM, all calls to this
* function, except the last one before mbedtls_cipher_finish(),
* must have ilen a multiple of the block size.
*/
int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input,
size_t ilen, unsigned char *output, size_t *olen );
/**
* \brief Generic cipher finalisation function. If data still
* needs to be flushed from an incomplete block, data
* contained within it will be padded with the size of
* the last block, and written to the output buffer.
*
* \param ctx Generic cipher context
* \param output buffer to write data to. Needs block_size available.
* \param olen length of the data written to the output buffer.
*
* \returns 0 on success, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if
* parameter verification fails,
* MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED if decryption
* expected a full block but was not provided one,
* MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
* while decrypting or a cipher specific error code.
*/
int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
unsigned char *output, size_t *olen );
#if defined(MBEDTLS_GCM_C)
/**
* \brief Write tag for AEAD ciphers.
* Currently only supported with GCM.
* Must be called after mbedtls_cipher_finish().
*
* \param ctx Generic cipher context
* \param tag buffer to write the tag
* \param tag_len Length of the tag to write
*
* \return 0 on success, or a specific error code.
*/
int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
unsigned char *tag, size_t tag_len );
/**
* \brief Check tag for AEAD ciphers.
* Currently only supported with GCM.
* Must be called after mbedtls_cipher_finish().
*
* \param ctx Generic cipher context
* \param tag Buffer holding the tag
* \param tag_len Length of the tag to check
*
* \return 0 on success, or a specific error code.
*/
int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
const unsigned char *tag, size_t tag_len );
#endif /* MBEDTLS_GCM_C */
/**
* \brief Generic all-in-one encryption/decryption
* (for all ciphers except AEAD constructs).
*
* \param ctx generic cipher context
* \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers)
* \param iv_len IV length for ciphers with variable-size IV;
* discarded by ciphers with fixed-size IV.
* \param input buffer holding the input data
* \param ilen length of the input data
* \param output buffer for the output data. Should be able to hold at
* least ilen + block_size. Cannot be the same buffer as
* input!
* \param olen length of the output data, will be filled with the
* actual number of bytes written.
*
* \note Some ciphers don't use IVs nor NONCE. For these
* ciphers, use iv = NULL and iv_len = 0.
*
* \returns 0 on success, or
* MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or
* MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED if decryption
* expected a full block but was not provided one, or
* MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
* while decrypting, or
* a cipher specific error code.
*/
int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
const unsigned char *iv, size_t iv_len,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen );
#if defined(MBEDTLS_CIPHER_MODE_AEAD)
/**
* \brief Generic autenticated encryption (AEAD ciphers).
*
* \param ctx generic cipher context
* \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers)
* \param iv_len IV length for ciphers with variable-size IV;
* discarded by ciphers with fixed-size IV.
* \param ad Additional data to authenticate.
* \param ad_len Length of ad.
* \param input buffer holding the input data
* \param ilen length of the input data
* \param output buffer for the output data.
* Should be able to hold at least ilen.
* \param olen length of the output data, will be filled with the
* actual number of bytes written.
* \param tag buffer for the authentication tag
* \param tag_len desired tag length
*
* \returns 0 on success, or
* MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or
* a cipher specific error code.
*/
int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
const unsigned char *iv, size_t iv_len,
const unsigned char *ad, size_t ad_len,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen,
unsigned char *tag, size_t tag_len );
/**
* \brief Generic autenticated decryption (AEAD ciphers).
*
* \param ctx generic cipher context
* \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers)
* \param iv_len IV length for ciphers with variable-size IV;
* discarded by ciphers with fixed-size IV.
* \param ad Additional data to be authenticated.
* \param ad_len Length of ad.
* \param input buffer holding the input data
* \param ilen length of the input data
* \param output buffer for the output data.
* Should be able to hold at least ilen.
* \param olen length of the output data, will be filled with the
* actual number of bytes written.
* \param tag buffer holding the authentication tag
* \param tag_len length of the authentication tag
*
* \returns 0 on success, or
* MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or
* MBEDTLS_ERR_CIPHER_AUTH_FAILED if data isn't authentic,
* or a cipher specific error code.
*
* \note If the data is not authentic, then the output buffer
* is zeroed out to prevent the unauthentic plaintext to
* be used by mistake, making this interface safer.
*/
int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
const unsigned char *iv, size_t iv_len,
const unsigned char *ad, size_t ad_len,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen,
const unsigned char *tag, size_t tag_len );
#endif /* MBEDTLS_CIPHER_MODE_AEAD */
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_CIPHER_H */

View file

@ -0,0 +1,109 @@
/**
* \file cipher_internal.h
*
* \brief Cipher wrappers.
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_CIPHER_WRAP_H
#define MBEDTLS_CIPHER_WRAP_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "cipher.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Base cipher information. The non-mode specific functions and values.
*/
struct mbedtls_cipher_base_t
{
/** Base Cipher type (e.g. MBEDTLS_CIPHER_ID_AES) */
mbedtls_cipher_id_t cipher;
/** Encrypt using ECB */
int (*ecb_func)( void *ctx, mbedtls_operation_t mode,
const unsigned char *input, unsigned char *output );
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/** Encrypt using CBC */
int (*cbc_func)( void *ctx, mbedtls_operation_t mode, size_t length,
unsigned char *iv, const unsigned char *input,
unsigned char *output );
#endif
#if defined(MBEDTLS_CIPHER_MODE_CFB)
/** Encrypt using CFB (Full length) */
int (*cfb_func)( void *ctx, mbedtls_operation_t mode, size_t length, size_t *iv_off,
unsigned char *iv, const unsigned char *input,
unsigned char *output );
#endif
#if defined(MBEDTLS_CIPHER_MODE_CTR)
/** Encrypt using CTR */
int (*ctr_func)( void *ctx, size_t length, size_t *nc_off,
unsigned char *nonce_counter, unsigned char *stream_block,
const unsigned char *input, unsigned char *output );
#endif
#if defined(MBEDTLS_CIPHER_MODE_STREAM)
/** Encrypt using STREAM */
int (*stream_func)( void *ctx, size_t length,
const unsigned char *input, unsigned char *output );
#endif
/** Set key for encryption purposes */
int (*setkey_enc_func)( void *ctx, const unsigned char *key,
unsigned int key_bitlen );
/** Set key for decryption purposes */
int (*setkey_dec_func)( void *ctx, const unsigned char *key,
unsigned int key_bitlen);
/** Allocate a new context */
void * (*ctx_alloc_func)( void );
/** Free the given context */
void (*ctx_free_func)( void *ctx );
};
typedef struct
{
mbedtls_cipher_type_t type;
const mbedtls_cipher_info_t *info;
} mbedtls_cipher_definition_t;
extern const mbedtls_cipher_definition_t mbedtls_cipher_definitions[];
extern int mbedtls_cipher_supported[];
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_CIPHER_WRAP_H */

View file

@ -0,0 +1,170 @@
/**
* \file cmac.h
*
* \brief Cipher-based Message Authentication Code (CMAC) Mode for
* Authentication
*
* Copyright (C) 2015-2016, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_CMAC_H
#define MBEDTLS_CMAC_H
#include "mbedtls/cipher.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MBEDTLS_AES_BLOCK_SIZE 16
#define MBEDTLS_DES3_BLOCK_SIZE 8
#if defined(MBEDTLS_AES_C)
#define MBEDTLS_CIPHER_BLKSIZE_MAX 16 /* longest used by CMAC is AES */
#else
#define MBEDTLS_CIPHER_BLKSIZE_MAX 8 /* longest used by CMAC is 3DES */
#endif
/**
* CMAC context structure - Contains internal state information only
*/
struct mbedtls_cmac_context_t
{
/** Internal state of the CMAC algorithm */
unsigned char state[MBEDTLS_CIPHER_BLKSIZE_MAX];
/** Unprocessed data - either data that was not block aligned and is still
* pending to be processed, or the final block */
unsigned char unprocessed_block[MBEDTLS_CIPHER_BLKSIZE_MAX];
/** Length of data pending to be processed */
size_t unprocessed_len;
};
/**
* \brief Set the CMAC key and prepare to authenticate the input
* data.
* Should be called with an initialized cipher context.
*
* \param ctx Cipher context. This should be a cipher context,
* initialized to be one of the following types:
* MBEDTLS_CIPHER_AES_128_ECB, MBEDTLS_CIPHER_AES_192_ECB,
* MBEDTLS_CIPHER_AES_256_ECB or
* MBEDTLS_CIPHER_DES_EDE3_ECB.
* \param key CMAC key
* \param keybits length of the CMAC key in bits
* (must be acceptable by the cipher)
*
* \return 0 if successful, or a cipher specific error code
*/
int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx,
const unsigned char *key, size_t keybits );
/**
* \brief Generic CMAC process buffer.
* Called between mbedtls_cipher_cmac_starts() or
* mbedtls_cipher_cmac_reset() and
* mbedtls_cipher_cmac_finish().
* May be called repeatedly.
*
* \param ctx CMAC context
* \param input buffer holding the data
* \param ilen length of the input data
*
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx,
const unsigned char *input, size_t ilen );
/**
* \brief Output CMAC.
* Called after mbedtls_cipher_cmac_update().
* Usually followed by mbedtls_cipher_cmac_reset(), then
* mbedtls_cipher_cmac_starts(), or mbedtls_cipher_free().
*
* \param ctx CMAC context
* \param output Generic CMAC checksum result
*
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx,
unsigned char *output );
/**
* \brief Prepare to authenticate a new message with the same key.
* Called after mbedtls_cipher_cmac_finish() and before
* mbedtls_cipher_cmac_update().
*
* \param ctx CMAC context to be reset
*
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx );
/**
* \brief Output = Generic_CMAC( cmac key, input buffer )
*
* \param cipher_info message digest info
* \param key CMAC key
* \param keylen length of the CMAC key in bits
* \param input buffer holding the data
* \param ilen length of the input data
* \param output Generic CMAC-result
*
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info,
const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char *output );
#if defined(MBEDTLS_AES_C)
/**
* \brief AES-CMAC-128-PRF
* Implementation of (AES-CMAC-PRF-128), as defined in RFC 4615
*
* \param key PRF key
* \param key_len PRF key length in bytes
* \param input buffer holding the input data
* \param in_len length of the input data in bytes
* \param output buffer holding the generated pseudorandom output (16 bytes)
*
* \return 0 if successful
*/
int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_len,
const unsigned char *input, size_t in_len,
unsigned char output[16] );
#endif /* MBEDTLS_AES_C */
#if defined(MBEDTLS_SELF_TEST) && ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) )
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mbedtls_cmac_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST && ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_CMAC_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,93 @@
/**
* \file config.h
*
* \brief Configuration options (set of defines)
*
* This set of compile-time options may be used to enable
* or disable features selectively, and reduce the global
* memory footprint.
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_CONFIG_H
#define MBEDTLS_CONFIG_H
/* crypto */
#define MBEDTLS_OID_C
#define MBEDTLS_CIPHER_MODE_CTR
#define MBEDTLS_GENPRIME
#define MBEDTLS_PKCS1_V21
#define MBEDTLS_RSA_NO_CRT
//#define MBEDTLS_SHA512_C
/* System support */
#define MBEDTLS_HAVE_ASM
/* mbed TLS feature support */
#define MBEDTLS_CIPHER_MODE_CBC
#define MBEDTLS_PKCS1_V15
#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
#define MBEDTLS_SSL_PROTO_TLS1_2
#define MBEDTLS_THREADING_C
#define MBEDTLS_THREADING_ALT
//#define MBEDTLS_THREADING_PTHREAD
/* mbed TLS modules */
#define MBEDTLS_AES_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_CIPHER_C
#define MBEDTLS_CIPHER_MODE_CFB
#define MBEDTLS_MD_C
#define MBEDTLS_MD5_C
#define MBEDTLS_NET_C
#define MBEDTLS_PK_C
#define MBEDTLS_PK_PARSE_C
#define MBEDTLS_RSA_C
#define MBEDTLS_SHA1_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_SSL_CLI_C
#define MBEDTLS_SSL_TLS_C
#define MBEDTLS_X509_CRT_PARSE_C
#define MBEDTLS_X509_USE_C
#define MBEDTLS_BASE64_C
#define MBEDTLS_PEM_PARSE_C
/* mbed TLS debug */
//#define MBEDTLS_DEBUG_C
/* OEM configure */
#define MBEDTLS_IOT_SPECIFIC
//#define MBEDTLS_PK_ALT
//#define MBEDTLS_AES_ALT
#define MBEDTLS_IOT_PLAT_AOS
#if defined(MBEDTLS_IOT_PLAT_AOS)
#define MBEDTLS_THREADING_ALT
#else
#define MBEDTLS_THREADING_PTHREAD
#endif /* MBEDTLS_IOT_PLAT_AOS */
#include "check_config.h"
#endif /* MBEDTLS_CONFIG_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,290 @@
/**
* \file ctr_drbg.h
*
* \brief CTR_DRBG based on AES-256 (NIST SP 800-90)
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_CTR_DRBG_H
#define MBEDTLS_CTR_DRBG_H
#include "aes.h"
#if defined(MBEDTLS_THREADING_C)
#include "mbedtls/threading.h"
#endif
#define MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED -0x0034 /**< The entropy source failed. */
#define MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG -0x0036 /**< Too many random requested in single call. */
#define MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG -0x0038 /**< Input too large (Entropy + additional). */
#define MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR -0x003A /**< Read/write error in file. */
#define MBEDTLS_CTR_DRBG_BLOCKSIZE 16 /**< Block size used by the cipher */
#define MBEDTLS_CTR_DRBG_KEYSIZE 32 /**< Key size used by the cipher */
#define MBEDTLS_CTR_DRBG_KEYBITS ( MBEDTLS_CTR_DRBG_KEYSIZE * 8 )
#define MBEDTLS_CTR_DRBG_SEEDLEN ( MBEDTLS_CTR_DRBG_KEYSIZE + MBEDTLS_CTR_DRBG_BLOCKSIZE )
/**< The seed length (counter + AES key) */
/**
* \name SECTION: Module settings
*
* The configuration options you can set for this module are in this section.
* Either change them in config.h or define them on the compiler command line.
* \{
*/
#if !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN)
#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256)
#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */
#else
#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 32 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */
#endif
#endif
#if !defined(MBEDTLS_CTR_DRBG_RESEED_INTERVAL)
#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */
#endif
#if !defined(MBEDTLS_CTR_DRBG_MAX_INPUT)
#define MBEDTLS_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */
#endif
#if !defined(MBEDTLS_CTR_DRBG_MAX_REQUEST)
#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */
#endif
#if !defined(MBEDTLS_CTR_DRBG_MAX_SEED_INPUT)
#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */
#endif
/* \} name SECTION: Module settings */
#define MBEDTLS_CTR_DRBG_PR_OFF 0 /**< No prediction resistance */
#define MBEDTLS_CTR_DRBG_PR_ON 1 /**< Prediction resistance enabled */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief CTR_DRBG context structure
*/
typedef struct
{
unsigned char counter[16]; /*!< counter (V) */
int reseed_counter; /*!< reseed counter */
int prediction_resistance; /*!< enable prediction resistance (Automatic
reseed before every random generation) */
size_t entropy_len; /*!< amount of entropy grabbed on each
(re)seed */
int reseed_interval; /*!< reseed interval */
mbedtls_aes_context aes_ctx; /*!< AES context */
/*
* Callbacks (Entropy)
*/
int (*f_entropy)(void *, unsigned char *, size_t);
void *p_entropy; /*!< context for the entropy function */
#if defined(MBEDTLS_THREADING_C)
mbedtls_threading_mutex_t mutex;
#endif
}
mbedtls_ctr_drbg_context;
/**
* \brief CTR_DRBG context initialization
* Makes the context ready for mbedtls_ctr_drbg_seed() or
* mbedtls_ctr_drbg_free().
*
* \param ctx CTR_DRBG context to be initialized
*/
void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
/**
* \brief CTR_DRBG initial seeding
* Seed and setup entropy source for future reseeds.
*
* Note: Personalization data can be provided in addition to the more generic
* entropy source to make this instantiation as unique as possible.
*
* \param ctx CTR_DRBG context to be seeded
* \param f_entropy Entropy callback (p_entropy, buffer to fill, buffer
* length)
* \param p_entropy Entropy context
* \param custom Personalization data (Device specific identifiers)
* (Can be NULL)
* \param len Length of personalization data
*
* \return 0 if successful, or
* MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED
*/
int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
int (*f_entropy)(void *, unsigned char *, size_t),
void *p_entropy,
const unsigned char *custom,
size_t len );
/**
* \brief Clear CTR_CRBG context data
*
* \param ctx CTR_DRBG context to clear
*/
void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx );
/**
* \brief Enable / disable prediction resistance (Default: Off)
*
* Note: If enabled, entropy is used for ctx->entropy_len before each call!
* Only use this if you have ample supply of good entropy!
*
* \param ctx CTR_DRBG context
* \param resistance MBEDTLS_CTR_DRBG_PR_ON or MBEDTLS_CTR_DRBG_PR_OFF
*/
void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx,
int resistance );
/**
* \brief Set the amount of entropy grabbed on each (re)seed
* (Default: MBEDTLS_CTR_DRBG_ENTROPY_LEN)
*
* \param ctx CTR_DRBG context
* \param len Amount of entropy to grab
*/
void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx,
size_t len );
/**
* \brief Set the reseed interval
* (Default: MBEDTLS_CTR_DRBG_RESEED_INTERVAL)
*
* \param ctx CTR_DRBG context
* \param interval Reseed interval
*/
void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx,
int interval );
/**
* \brief CTR_DRBG reseeding (extracts data from entropy source)
*
* \param ctx CTR_DRBG context
* \param additional Additional data to add to state (Can be NULL)
* \param len Length of additional data
*
* \return 0 if successful, or
* MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED
*/
int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
const unsigned char *additional, size_t len );
/**
* \brief CTR_DRBG update state
*
* \param ctx CTR_DRBG context
* \param additional Additional data to update state with
* \param add_len Length of additional data
*
* \note If add_len is greater than MBEDTLS_CTR_DRBG_MAX_SEED_INPUT,
* only the first MBEDTLS_CTR_DRBG_MAX_SEED_INPUT bytes are used,
* the remaining ones are silently discarded.
*/
void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
const unsigned char *additional, size_t add_len );
/**
* \brief CTR_DRBG generate random with additional update input
*
* Note: Automatically reseeds if reseed_counter is reached.
*
* \param p_rng CTR_DRBG context
* \param output Buffer to fill
* \param output_len Length of the buffer
* \param additional Additional data to update with (Can be NULL)
* \param add_len Length of additional data
*
* \return 0 if successful, or
* MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED, or
* MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG
*/
int mbedtls_ctr_drbg_random_with_add( void *p_rng,
unsigned char *output, size_t output_len,
const unsigned char *additional, size_t add_len );
/**
* \brief CTR_DRBG generate random
*
* Note: Automatically reseeds if reseed_counter is reached.
*
* \param p_rng CTR_DRBG context
* \param output Buffer to fill
* \param output_len Length of the buffer
*
* \return 0 if successful, or
* MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED, or
* MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG
*/
int mbedtls_ctr_drbg_random( void *p_rng,
unsigned char *output, size_t output_len );
#if defined(MBEDTLS_FS_IO)
/**
* \brief Write a seed file
*
* \param ctx CTR_DRBG context
* \param path Name of the file
*
* \return 0 if successful,
* MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error, or
* MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED
*/
int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path );
/**
* \brief Read and update a seed file. Seed is added to this
* instance
*
* \param ctx CTR_DRBG context
* \param path Name of the file
*
* \return 0 if successful,
* MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error,
* MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
* MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG
*/
int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path );
#endif /* MBEDTLS_FS_IO */
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mbedtls_ctr_drbg_self_test( int verbose );
/* Internal functions (do not call directly) */
int mbedtls_ctr_drbg_seed_entropy_len( mbedtls_ctr_drbg_context *,
int (*)(void *, unsigned char *, size_t), void *,
const unsigned char *, size_t, size_t );
#ifdef __cplusplus
}
#endif
#endif /* ctr_drbg.h */

View file

@ -0,0 +1,228 @@
/**
* \file debug.h
*
* \brief Functions for controlling and providing debug output from the library.
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_DEBUG_H
#define MBEDTLS_DEBUG_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "ssl.h"
#if defined(MBEDTLS_ECP_C)
#include "ecp.h"
#endif
#if defined(MBEDTLS_DEBUG_C)
#define MBEDTLS_DEBUG_STRIP_PARENS( ... ) __VA_ARGS__
#define MBEDTLS_SSL_DEBUG_MSG( level, args ) \
mbedtls_debug_print_msg( ssl, level, __FILE__, __LINE__, \
MBEDTLS_DEBUG_STRIP_PARENS args )
#define MBEDTLS_SSL_DEBUG_RET( level, text, ret ) \
mbedtls_debug_print_ret( ssl, level, __FILE__, __LINE__, text, ret )
#define MBEDTLS_SSL_DEBUG_BUF( level, text, buf, len ) \
mbedtls_debug_print_buf( ssl, level, __FILE__, __LINE__, text, buf, len )
#if defined(MBEDTLS_BIGNUM_C)
#define MBEDTLS_SSL_DEBUG_MPI( level, text, X ) \
mbedtls_debug_print_mpi( ssl, level, __FILE__, __LINE__, text, X )
#endif
#if defined(MBEDTLS_ECP_C)
#define MBEDTLS_SSL_DEBUG_ECP( level, text, X ) \
mbedtls_debug_print_ecp( ssl, level, __FILE__, __LINE__, text, X )
#endif
#if defined(MBEDTLS_X509_CRT_PARSE_C)
#define MBEDTLS_SSL_DEBUG_CRT( level, text, crt ) \
mbedtls_debug_print_crt( ssl, level, __FILE__, __LINE__, text, crt )
#endif
#else /* MBEDTLS_DEBUG_C */
#define MBEDTLS_SSL_DEBUG_MSG( level, args ) do { } while( 0 )
#define MBEDTLS_SSL_DEBUG_RET( level, text, ret ) do { } while( 0 )
#define MBEDTLS_SSL_DEBUG_BUF( level, text, buf, len ) do { } while( 0 )
#define MBEDTLS_SSL_DEBUG_MPI( level, text, X ) do { } while( 0 )
#define MBEDTLS_SSL_DEBUG_ECP( level, text, X ) do { } while( 0 )
#define MBEDTLS_SSL_DEBUG_CRT( level, text, crt ) do { } while( 0 )
#endif /* MBEDTLS_DEBUG_C */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Set the threshold error level to handle globally all debug output.
* Debug messages that have a level over the threshold value are
* discarded.
* (Default value: 0 = No debug )
*
* \param threshold theshold level of messages to filter on. Messages at a
* higher level will be discarded.
* - Debug levels
* - 0 No debug
* - 1 Error
* - 2 State change
* - 3 Informational
* - 4 Verbose
*/
void mbedtls_debug_set_threshold( int threshold );
/**
* \brief Print a message to the debug output. This function is always used
* through the MBEDTLS_SSL_DEBUG_MSG() macro, which supplies the ssl
* context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the message has occurred in
* \param line line number the message has occurred at
* \param format format specifier, in printf format
* \param ... variables used by the format specifier
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *format, ... );
/**
* \brief Print the return value of a function to the debug output. This
* function is always used through the MBEDTLS_SSL_DEBUG_RET() macro,
* which supplies the ssl context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param text the name of the function that returned the error
* \param ret the return code value
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_ret( const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, int ret );
/**
* \brief Output a buffer of size len bytes to the debug output. This function
* is always used through the MBEDTLS_SSL_DEBUG_BUF() macro,
* which supplies the ssl context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param text a name or label for the buffer being dumped. Normally the
* variable or buffer name
* \param buf the buffer to be outputted
* \param len length of the buffer
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_buf( const mbedtls_ssl_context *ssl, int level,
const char *file, int line, const char *text,
const unsigned char *buf, size_t len );
#if defined(MBEDTLS_BIGNUM_C)
/**
* \brief Print a MPI variable to the debug output. This function is always
* used through the MBEDTLS_SSL_DEBUG_MPI() macro, which supplies the
* ssl context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param text a name or label for the MPI being output. Normally the
* variable name
* \param X the MPI variable
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_mpi( const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mbedtls_mpi *X );
#endif
#if defined(MBEDTLS_ECP_C)
/**
* \brief Print an ECP point to the debug output. This function is always
* used through the MBEDTLS_SSL_DEBUG_ECP() macro, which supplies the
* ssl context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param text a name or label for the ECP point being output. Normally the
* variable name
* \param X the ECP point
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_ecp( const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mbedtls_ecp_point *X );
#endif
#if defined(MBEDTLS_X509_CRT_PARSE_C)
/**
* \brief Print a X.509 certificate structure to the debug output. This
* function is always used through the MBEDTLS_SSL_DEBUG_CRT() macro,
* which supplies the ssl context, file and line number parameters.
*
* \param ssl SSL context
* \param level error level of the debug message
* \param file file the error has occurred in
* \param line line number the error has occurred in
* \param text a name or label for the certificate being output
* \param crt X.509 certificate structure
*
* \attention This function is intended for INTERNAL usage within the
* library only.
*/
void mbedtls_debug_print_crt( const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mbedtls_x509_crt *crt );
#endif
#ifdef __cplusplus
}
#endif
#endif /* debug.h */

View file

@ -0,0 +1,306 @@
/**
* \file des.h
*
* \brief DES block cipher
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_DES_H
#define MBEDTLS_DES_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include <stdint.h>
#define MBEDTLS_DES_ENCRYPT 1
#define MBEDTLS_DES_DECRYPT 0
#define MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH -0x0032 /**< The data input has an invalid length. */
#define MBEDTLS_DES_KEY_SIZE 8
#if !defined(MBEDTLS_DES_ALT)
// Regular implementation
//
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief DES context structure
*/
typedef struct
{
uint32_t sk[32]; /*!< DES subkeys */
}
mbedtls_des_context;
/**
* \brief Triple-DES context structure
*/
typedef struct
{
uint32_t sk[96]; /*!< 3DES subkeys */
}
mbedtls_des3_context;
/**
* \brief Initialize DES context
*
* \param ctx DES context to be initialized
*/
void mbedtls_des_init( mbedtls_des_context *ctx );
/**
* \brief Clear DES context
*
* \param ctx DES context to be cleared
*/
void mbedtls_des_free( mbedtls_des_context *ctx );
/**
* \brief Initialize Triple-DES context
*
* \param ctx DES3 context to be initialized
*/
void mbedtls_des3_init( mbedtls_des3_context *ctx );
/**
* \brief Clear Triple-DES context
*
* \param ctx DES3 context to be cleared
*/
void mbedtls_des3_free( mbedtls_des3_context *ctx );
/**
* \brief Set key parity on the given key to odd.
*
* DES keys are 56 bits long, but each byte is padded with
* a parity bit to allow verification.
*
* \param key 8-byte secret key
*/
void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] );
/**
* \brief Check that key parity on the given key is odd.
*
* DES keys are 56 bits long, but each byte is padded with
* a parity bit to allow verification.
*
* \param key 8-byte secret key
*
* \return 0 is parity was ok, 1 if parity was not correct.
*/
int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
/**
* \brief Check that key is not a weak or semi-weak DES key
*
* \param key 8-byte secret key
*
* \return 0 if no weak key was found, 1 if a weak key was identified.
*/
int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
/**
* \brief DES key schedule (56-bit, encryption)
*
* \param ctx DES context to be initialized
* \param key 8-byte secret key
*
* \return 0
*/
int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
/**
* \brief DES key schedule (56-bit, decryption)
*
* \param ctx DES context to be initialized
* \param key 8-byte secret key
*
* \return 0
*/
int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
/**
* \brief Triple-DES key schedule (112-bit, encryption)
*
* \param ctx 3DES context to be initialized
* \param key 16-byte secret key
*
* \return 0
*/
int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] );
/**
* \brief Triple-DES key schedule (112-bit, decryption)
*
* \param ctx 3DES context to be initialized
* \param key 16-byte secret key
*
* \return 0
*/
int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] );
/**
* \brief Triple-DES key schedule (168-bit, encryption)
*
* \param ctx 3DES context to be initialized
* \param key 24-byte secret key
*
* \return 0
*/
int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] );
/**
* \brief Triple-DES key schedule (168-bit, decryption)
*
* \param ctx 3DES context to be initialized
* \param key 24-byte secret key
*
* \return 0
*/
int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] );
/**
* \brief DES-ECB block encryption/decryption
*
* \param ctx DES context
* \param input 64-bit input block
* \param output 64-bit output block
*
* \return 0 if successful
*/
int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
const unsigned char input[8],
unsigned char output[8] );
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/**
* \brief DES-CBC buffer encryption/decryption
*
* \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx DES context
* \param mode MBEDTLS_DES_ENCRYPT or MBEDTLS_DES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*/
int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
int mode,
size_t length,
unsigned char iv[8],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CBC */
/**
* \brief 3DES-ECB block encryption/decryption
*
* \param ctx 3DES context
* \param input 64-bit input block
* \param output 64-bit output block
*
* \return 0 if successful
*/
int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
const unsigned char input[8],
unsigned char output[8] );
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/**
* \brief 3DES-CBC buffer encryption/decryption
*
* \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx 3DES context
* \param mode MBEDTLS_DES_ENCRYPT or MBEDTLS_DES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful, or MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH
*/
int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
int mode,
size_t length,
unsigned char iv[8],
const unsigned char *input,
unsigned char *output );
#endif /* MBEDTLS_CIPHER_MODE_CBC */
/**
* \brief Internal function for key expansion.
* (Only exposed to allow overriding it,
* see MBEDTLS_DES_SETKEY_ALT)
*
* \param SK Round keys
* \param key Base key
*/
void mbedtls_des_setkey( uint32_t SK[32],
const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
#ifdef __cplusplus
}
#endif
#else /* MBEDTLS_DES_ALT */
#include "des_alt.h"
#endif /* MBEDTLS_DES_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mbedtls_des_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* des.h */

View file

@ -0,0 +1,305 @@
/**
* \file dhm.h
*
* \brief Diffie-Hellman-Merkle key exchange
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_DHM_H
#define MBEDTLS_DHM_H
#include "bignum.h"
/*
* DHM Error codes
*/
#define MBEDTLS_ERR_DHM_BAD_INPUT_DATA -0x3080 /**< Bad input parameters to function. */
#define MBEDTLS_ERR_DHM_READ_PARAMS_FAILED -0x3100 /**< Reading of the DHM parameters failed. */
#define MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED -0x3180 /**< Making of the DHM parameters failed. */
#define MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED -0x3200 /**< Reading of the public values failed. */
#define MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED -0x3280 /**< Making of the public value failed. */
#define MBEDTLS_ERR_DHM_CALC_SECRET_FAILED -0x3300 /**< Calculation of the DHM secret failed. */
#define MBEDTLS_ERR_DHM_INVALID_FORMAT -0x3380 /**< The ASN.1 data is not formatted correctly. */
#define MBEDTLS_ERR_DHM_ALLOC_FAILED -0x3400 /**< Allocation of memory failed. */
#define MBEDTLS_ERR_DHM_FILE_IO_ERROR -0x3480 /**< Read/write of file failed. */
/**
* RFC 3526 defines a number of standardized Diffie-Hellman groups
* for IKE.
* RFC 5114 defines a number of standardized Diffie-Hellman groups
* that can be used.
*
* Some are included here for convenience.
*
* Included are:
* RFC 3526 3. 2048-bit MODP Group
* RFC 3526 4. 3072-bit MODP Group
* RFC 3526 5. 4096-bit MODP Group
* RFC 5114 2.2. 2048-bit MODP Group with 224-bit Prime Order Subgroup
*/
#define MBEDTLS_DHM_RFC3526_MODP_2048_P \
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \
"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \
"83655D23DCA3AD961C62F356208552BB9ED529077096966D" \
"670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \
"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \
"DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \
"15728E5A8AACAA68FFFFFFFFFFFFFFFF"
#define MBEDTLS_DHM_RFC3526_MODP_2048_G "02"
#define MBEDTLS_DHM_RFC3526_MODP_3072_P \
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \
"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \
"83655D23DCA3AD961C62F356208552BB9ED529077096966D" \
"670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \
"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \
"DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \
"15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" \
"ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" \
"ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" \
"F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" \
"BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" \
"43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF"
#define MBEDTLS_DHM_RFC3526_MODP_3072_G "02"
#define MBEDTLS_DHM_RFC3526_MODP_4096_P \
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \
"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \
"83655D23DCA3AD961C62F356208552BB9ED529077096966D" \
"670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \
"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \
"DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \
"15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" \
"ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" \
"ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" \
"F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" \
"BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" \
"43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" \
"88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" \
"2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" \
"287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" \
"1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" \
"93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199" \
"FFFFFFFFFFFFFFFF"
#define MBEDTLS_DHM_RFC3526_MODP_4096_G "02"
#define MBEDTLS_DHM_RFC5114_MODP_2048_P \
"AD107E1E9123A9D0D660FAA79559C51FA20D64E5683B9FD1" \
"B54B1597B61D0A75E6FA141DF95A56DBAF9A3C407BA1DF15" \
"EB3D688A309C180E1DE6B85A1274A0A66D3F8152AD6AC212" \
"9037C9EDEFDA4DF8D91E8FEF55B7394B7AD5B7D0B6C12207" \
"C9F98D11ED34DBF6C6BA0B2C8BBC27BE6A00E0A0B9C49708" \
"B3BF8A317091883681286130BC8985DB1602E714415D9330" \
"278273C7DE31EFDC7310F7121FD5A07415987D9ADC0A486D" \
"CDF93ACC44328387315D75E198C641A480CD86A1B9E587E8" \
"BE60E69CC928B2B9C52172E413042E9B23F10B0E16E79763" \
"C9B53DCF4BA80A29E3FB73C16B8E75B97EF363E2FFA31F71" \
"CF9DE5384E71B81C0AC4DFFE0C10E64F"
#define MBEDTLS_DHM_RFC5114_MODP_2048_G \
"AC4032EF4F2D9AE39DF30B5C8FFDAC506CDEBE7B89998CAF"\
"74866A08CFE4FFE3A6824A4E10B9A6F0DD921F01A70C4AFA"\
"AB739D7700C29F52C57DB17C620A8652BE5E9001A8D66AD7"\
"C17669101999024AF4D027275AC1348BB8A762D0521BC98A"\
"E247150422EA1ED409939D54DA7460CDB5F6C6B250717CBE"\
"F180EB34118E98D119529A45D6F834566E3025E316A330EF"\
"BB77A86F0C1AB15B051AE3D428C8F8ACB70A8137150B8EEB"\
"10E183EDD19963DDD9E263E4770589EF6AA21E7F5F2FF381"\
"B539CCE3409D13CD566AFBB48D6C019181E1BCFE94B30269"\
"EDFE72FE9B6AA4BD7B5A0F1C71CFFF4C19C418E1F6EC0179"\
"81BC087F2A7065B384B890D3191F2BFA"
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief DHM context structure
*/
typedef struct
{
size_t len; /*!< size(P) in chars */
mbedtls_mpi P; /*!< prime modulus */
mbedtls_mpi G; /*!< generator */
mbedtls_mpi X; /*!< secret value */
mbedtls_mpi GX; /*!< self = G^X mod P */
mbedtls_mpi GY; /*!< peer = G^Y mod P */
mbedtls_mpi K; /*!< key = GY^X mod P */
mbedtls_mpi RP; /*!< cached R^2 mod P */
mbedtls_mpi Vi; /*!< blinding value */
mbedtls_mpi Vf; /*!< un-blinding value */
mbedtls_mpi pX; /*!< previous X */
}
mbedtls_dhm_context;
/**
* \brief Initialize DHM context
*
* \param ctx DHM context to be initialized
*/
void mbedtls_dhm_init( mbedtls_dhm_context *ctx );
/**
* \brief Parse the ServerKeyExchange parameters
*
* \param ctx DHM context
* \param p &(start of input buffer)
* \param end end of buffer
*
* \return 0 if successful, or an MBEDTLS_ERR_DHM_XXX error code
*/
int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx,
unsigned char **p,
const unsigned char *end );
/**
* \brief Setup and write the ServerKeyExchange parameters
*
* \param ctx DHM context
* \param x_size private value size in bytes
* \param output destination buffer
* \param olen number of chars written
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \note This function assumes that ctx->P and ctx->G
* have already been properly set (for example
* using mbedtls_mpi_read_string or mbedtls_mpi_read_binary).
*
* \return 0 if successful, or an MBEDTLS_ERR_DHM_XXX error code
*/
int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
unsigned char *output, size_t *olen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Import the peer's public value G^Y
*
* \param ctx DHM context
* \param input input buffer
* \param ilen size of buffer
*
* \return 0 if successful, or an MBEDTLS_ERR_DHM_XXX error code
*/
int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx,
const unsigned char *input, size_t ilen );
/**
* \brief Create own private value X and export G^X
*
* \param ctx DHM context
* \param x_size private value size in bytes
* \param output destination buffer
* \param olen must be at least equal to the size of P, ctx->len
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successful, or an MBEDTLS_ERR_DHM_XXX error code
*/
int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size,
unsigned char *output, size_t olen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Derive and export the shared secret (G^Y)^X mod P
*
* \param ctx DHM context
* \param output destination buffer
* \param output_size size of the destination buffer
* \param olen on exit, holds the actual number of bytes written
* \param f_rng RNG function, for blinding purposes
* \param p_rng RNG parameter
*
* \return 0 if successful, or an MBEDTLS_ERR_DHM_XXX error code
*
* \note If non-NULL, f_rng is used to blind the input as
* countermeasure against timing attacks. Blinding is
* automatically used if and only if our secret value X is
* re-used and costs nothing otherwise, so it is recommended
* to always pass a non-NULL f_rng argument.
*/
int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
unsigned char *output, size_t output_size, size_t *olen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Free and clear the components of a DHM key
*
* \param ctx DHM context to free and clear
*/
void mbedtls_dhm_free( mbedtls_dhm_context *ctx );
#if defined(MBEDTLS_ASN1_PARSE_C)
/** \ingroup x509_module */
/**
* \brief Parse DHM parameters in PEM or DER format
*
* \param dhm DHM context to be initialized
* \param dhmin input buffer
* \param dhminlen size of the buffer
* (including the terminating null byte for PEM data)
*
* \return 0 if successful, or a specific DHM or PEM error code
*/
int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
size_t dhminlen );
#if defined(MBEDTLS_FS_IO)
/** \ingroup x509_module */
/**
* \brief Load and parse DHM parameters
*
* \param dhm DHM context to be initialized
* \param path filename to read the DHM Parameters from
*
* \return 0 if successful, or a specific DHM or PEM error code
*/
int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path );
#endif /* MBEDTLS_FS_IO */
#endif /* MBEDTLS_ASN1_PARSE_C */
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mbedtls_dhm_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* dhm.h */

View file

@ -0,0 +1,214 @@
/**
* \file ecdh.h
*
* \brief Elliptic curve Diffie-Hellman
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_ECDH_H
#define MBEDTLS_ECDH_H
#include "ecp.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* When importing from an EC key, select if it is our key or the peer's key
*/
typedef enum
{
MBEDTLS_ECDH_OURS,
MBEDTLS_ECDH_THEIRS,
} mbedtls_ecdh_side;
/**
* \brief ECDH context structure
*/
typedef struct
{
mbedtls_ecp_group grp; /*!< elliptic curve used */
mbedtls_mpi d; /*!< our secret value (private key) */
mbedtls_ecp_point Q; /*!< our public value (public key) */
mbedtls_ecp_point Qp; /*!< peer's public value (public key) */
mbedtls_mpi z; /*!< shared secret */
int point_format; /*!< format for point export in TLS messages */
mbedtls_ecp_point Vi; /*!< blinding value (for later) */
mbedtls_ecp_point Vf; /*!< un-blinding value (for later) */
mbedtls_mpi _d; /*!< previous d (for later) */
}
mbedtls_ecdh_context;
/**
* \brief Generate a public key.
* Raw function that only does the core computation.
*
* \param grp ECP group
* \param d Destination MPI (secret exponent, aka private key)
* \param Q Destination point (public key)
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successful,
* or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code
*/
int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Compute shared secret
* Raw function that only does the core computation.
*
* \param grp ECP group
* \param z Destination MPI (shared secret)
* \param Q Public key from other party
* \param d Our secret exponent (private key)
* \param f_rng RNG function (see notes)
* \param p_rng RNG parameter
*
* \return 0 if successful,
* or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code
*
* \note If f_rng is not NULL, it is used to implement
* countermeasures against potential elaborate timing
* attacks, see \c mbedtls_ecp_mul() for details.
*/
int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z,
const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Initialize context
*
* \param ctx Context to initialize
*/
void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx );
/**
* \brief Free context
*
* \param ctx Context to free
*/
void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx );
/**
* \brief Generate a public key and a TLS ServerKeyExchange payload.
* (First function used by a TLS server for ECDHE.)
*
* \param ctx ECDH context
* \param olen number of chars written
* \param buf destination buffer
* \param blen length of buffer
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \note This function assumes that ctx->grp has already been
* properly set (for example using mbedtls_ecp_group_load).
*
* \return 0 if successful, or an MBEDTLS_ERR_ECP_XXX error code
*/
int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Parse and procress a TLS ServerKeyExhange payload.
* (First function used by a TLS client for ECDHE.)
*
* \param ctx ECDH context
* \param buf pointer to start of input buffer
* \param end one past end of buffer
*
* \return 0 if successful, or an MBEDTLS_ERR_ECP_XXX error code
*/
int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx,
const unsigned char **buf, const unsigned char *end );
/**
* \brief Setup an ECDH context from an EC key.
* (Used by clients and servers in place of the
* ServerKeyEchange for static ECDH: import ECDH parameters
* from a certificate's EC key information.)
*
* \param ctx ECDH constext to set
* \param key EC key to use
* \param side Is it our key (1) or the peer's key (0) ?
*
* \return 0 if successful, or an MBEDTLS_ERR_ECP_XXX error code
*/
int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, const mbedtls_ecp_keypair *key,
mbedtls_ecdh_side side );
/**
* \brief Generate a public key and a TLS ClientKeyExchange payload.
* (Second function used by a TLS client for ECDH(E).)
*
* \param ctx ECDH context
* \param olen number of bytes actually written
* \param buf destination buffer
* \param blen size of destination buffer
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successful, or an MBEDTLS_ERR_ECP_XXX error code
*/
int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Parse and process a TLS ClientKeyExchange payload.
* (Second function used by a TLS server for ECDH(E).)
*
* \param ctx ECDH context
* \param buf start of input buffer
* \param blen length of input buffer
*
* \return 0 if successful, or an MBEDTLS_ERR_ECP_XXX error code
*/
int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx,
const unsigned char *buf, size_t blen );
/**
* \brief Derive and export the shared secret.
* (Last function used by both TLS client en servers.)
*
* \param ctx ECDH context
* \param olen number of bytes written
* \param buf destination buffer
* \param blen buffer length
* \param f_rng RNG function, see notes for \c mbedtls_ecdh_compute_shared()
* \param p_rng RNG parameter
*
* \return 0 if successful, or an MBEDTLS_ERR_ECP_XXX error code
*/
int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
#ifdef __cplusplus
}
#endif
#endif /* ecdh.h */

View file

@ -0,0 +1,248 @@
/**
* \file ecdsa.h
*
* \brief Elliptic curve DSA
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_ECDSA_H
#define MBEDTLS_ECDSA_H
#include "ecp.h"
#include "md.h"
/*
* RFC 4492 page 20:
*
* Ecdsa-Sig-Value ::= SEQUENCE {
* r INTEGER,
* s INTEGER
* }
*
* Size is at most
* 1 (tag) + 1 (len) + 1 (initial 0) + ECP_MAX_BYTES for each of r and s,
* twice that + 1 (tag) + 2 (len) for the sequence
* (assuming ECP_MAX_BYTES is less than 126 for r and s,
* and less than 124 (total len <= 255) for the sequence)
*/
#if MBEDTLS_ECP_MAX_BYTES > 124
#error "MBEDTLS_ECP_MAX_BYTES bigger than expected, please fix MBEDTLS_ECDSA_MAX_LEN"
#endif
/** Maximum size of an ECDSA signature in bytes */
#define MBEDTLS_ECDSA_MAX_LEN ( 3 + 2 * ( 3 + MBEDTLS_ECP_MAX_BYTES ) )
/**
* \brief ECDSA context structure
*/
typedef mbedtls_ecp_keypair mbedtls_ecdsa_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Compute ECDSA signature of a previously hashed message
*
* \note The deterministic version is usually prefered.
*
* \param grp ECP group
* \param r First output integer
* \param s Second output integer
* \param d Private signing key
* \param buf Message hash
* \param blen Length of buf
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successful,
* or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code
*/
int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
/**
* \brief Compute ECDSA signature of a previously hashed message,
* deterministic version (RFC 6979).
*
* \param grp ECP group
* \param r First output integer
* \param s Second output integer
* \param d Private signing key
* \param buf Message hash
* \param blen Length of buf
* \param md_alg MD algorithm used to hash the message
*
* \return 0 if successful,
* or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code
*/
int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
mbedtls_md_type_t md_alg );
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
/**
* \brief Verify ECDSA signature of a previously hashed message
*
* \param grp ECP group
* \param buf Message hash
* \param blen Length of buf
* \param Q Public key to use for verification
* \param r First integer of the signature
* \param s Second integer of the signature
*
* \return 0 if successful,
* MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid
* or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code
*/
int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
const unsigned char *buf, size_t blen,
const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s);
/**
* \brief Compute ECDSA signature and write it to buffer,
* serialized as defined in RFC 4492 page 20.
* (Not thread-safe to use same context in multiple threads)
*
* \note The deterministice version (RFC 6979) is used if
* MBEDTLS_ECDSA_DETERMINISTIC is defined.
*
* \param ctx ECDSA context
* \param md_alg Algorithm that was used to hash the message
* \param hash Message hash
* \param hlen Length of hash
* \param sig Buffer that will hold the signature
* \param slen Length of the signature written
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \note The "sig" buffer must be at least as large as twice the
* size of the curve used, plus 9 (eg. 73 bytes if a 256-bit
* curve is used). MBEDTLS_ECDSA_MAX_LEN is always safe.
*
* \return 0 if successful,
* or a MBEDTLS_ERR_ECP_XXX, MBEDTLS_ERR_MPI_XXX or
* MBEDTLS_ERR_ASN1_XXX error code
*/
int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hlen,
unsigned char *sig, size_t *slen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief Compute ECDSA signature and write it to buffer,
* serialized as defined in RFC 4492 page 20.
* Deterministic version, RFC 6979.
* (Not thread-safe to use same context in multiple threads)
*
* \deprecated Superseded by mbedtls_ecdsa_write_signature() in 2.0.0
*
* \param ctx ECDSA context
* \param hash Message hash
* \param hlen Length of hash
* \param sig Buffer that will hold the signature
* \param slen Length of the signature written
* \param md_alg MD algorithm used to hash the message
*
* \note The "sig" buffer must be at least as large as twice the
* size of the curve used, plus 9 (eg. 73 bytes if a 256-bit
* curve is used). MBEDTLS_ECDSA_MAX_LEN is always safe.
*
* \return 0 if successful,
* or a MBEDTLS_ERR_ECP_XXX, MBEDTLS_ERR_MPI_XXX or
* MBEDTLS_ERR_ASN1_XXX error code
*/
int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx,
const unsigned char *hash, size_t hlen,
unsigned char *sig, size_t *slen,
mbedtls_md_type_t md_alg ) MBEDTLS_DEPRECATED;
#undef MBEDTLS_DEPRECATED
#endif /* MBEDTLS_DEPRECATED_REMOVED */
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
/**
* \brief Read and verify an ECDSA signature
*
* \param ctx ECDSA context
* \param hash Message hash
* \param hlen Size of hash
* \param sig Signature to read and verify
* \param slen Size of sig
*
* \return 0 if successful,
* MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid,
* MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if the signature is
* valid but its actual length is less than siglen,
* or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_ERR_MPI_XXX error code
*/
int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx,
const unsigned char *hash, size_t hlen,
const unsigned char *sig, size_t slen );
/**
* \brief Generate an ECDSA keypair on the given curve
*
* \param ctx ECDSA context in which the keypair should be stored
* \param gid Group (elliptic curve) to use. One of the various
* MBEDTLS_ECP_DP_XXX macros depending on configuration.
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 on success, or a MBEDTLS_ERR_ECP_XXX code.
*/
int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
/**
* \brief Set an ECDSA context from an EC key pair
*
* \param ctx ECDSA context to set
* \param key EC key to use
*
* \return 0 on success, or a MBEDTLS_ERR_ECP_XXX code.
*/
int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key );
/**
* \brief Initialize context
*
* \param ctx Context to initialize
*/
void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx );
/**
* \brief Free context
*
* \param ctx Context to free
*/
void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx );
#ifdef __cplusplus
}
#endif
#endif /* ecdsa.h */

View file

@ -0,0 +1,238 @@
/**
* \file ecjpake.h
*
* \brief Elliptic curve J-PAKE
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_ECJPAKE_H
#define MBEDTLS_ECJPAKE_H
/*
* J-PAKE is a password-authenticated key exchange that allows deriving a
* strong shared secret from a (potentially low entropy) pre-shared
* passphrase, with forward secrecy and mutual authentication.
* https://en.wikipedia.org/wiki/Password_Authenticated_Key_Exchange_by_Juggling
*
* This file implements the Elliptic Curve variant of J-PAKE,
* as defined in Chapter 7.4 of the Thread v1.0 Specification,
* available to members of the Thread Group http://threadgroup.org/
*
* As the J-PAKE algorithm is inherently symmetric, so is our API.
* Each party needs to send its first round message, in any order, to the
* other party, then each sends its second round message, in any order.
* The payloads are serialized in a way suitable for use in TLS, but could
* also be use outside TLS.
*/
#include "ecp.h"
#include "md.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Roles in the EC J-PAKE exchange
*/
typedef enum {
MBEDTLS_ECJPAKE_CLIENT = 0, /**< Client */
MBEDTLS_ECJPAKE_SERVER, /**< Server */
} mbedtls_ecjpake_role;
/**
* EC J-PAKE context structure.
*
* J-PAKE is a symmetric protocol, except for the identifiers used in
* Zero-Knowledge Proofs, and the serialization of the second message
* (KeyExchange) as defined by the Thread spec.
*
* In order to benefit from this symmetry, we choose a different naming
* convetion from the Thread v1.0 spec. Correspondance is indicated in the
* description as a pair C: client name, S: server name
*/
typedef struct
{
const mbedtls_md_info_t *md_info; /**< Hash to use */
mbedtls_ecp_group grp; /**< Elliptic curve */
mbedtls_ecjpake_role role; /**< Are we client or server? */
int point_format; /**< Format for point export */
mbedtls_ecp_point Xm1; /**< My public key 1 C: X1, S: X3 */
mbedtls_ecp_point Xm2; /**< My public key 2 C: X2, S: X4 */
mbedtls_ecp_point Xp1; /**< Peer public key 1 C: X3, S: X1 */
mbedtls_ecp_point Xp2; /**< Peer public key 2 C: X4, S: X2 */
mbedtls_ecp_point Xp; /**< Peer public key C: Xs, S: Xc */
mbedtls_mpi xm1; /**< My private key 1 C: x1, S: x3 */
mbedtls_mpi xm2; /**< My private key 2 C: x2, S: x4 */
mbedtls_mpi s; /**< Pre-shared secret (passphrase) */
} mbedtls_ecjpake_context;
/**
* \brief Initialize a context
* (just makes it ready for setup() or free()).
*
* \param ctx context to initialize
*/
void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx );
/**
* \brief Set up a context for use
*
* \note Currently the only values for hash/curve allowed by the
* standard are MBEDTLS_MD_SHA256/MBEDTLS_ECP_DP_SECP256R1.
*
* \param ctx context to set up
* \param role Our role: client or server
* \param hash hash function to use (MBEDTLS_MD_XXX)
* \param curve elliptic curve identifier (MBEDTLS_ECP_DP_XXX)
* \param secret pre-shared secret (passphrase)
* \param len length of the shared secret
*
* \return 0 if successfull,
* a negative error code otherwise
*/
int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx,
mbedtls_ecjpake_role role,
mbedtls_md_type_t hash,
mbedtls_ecp_group_id curve,
const unsigned char *secret,
size_t len );
/*
* \brief Check if a context is ready for use
*
* \param ctx Context to check
*
* \return 0 if the context is ready for use,
* MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise
*/
int mbedtls_ecjpake_check( const mbedtls_ecjpake_context *ctx );
/**
* \brief Generate and write the first round message
* (TLS: contents of the Client/ServerHello extension,
* excluding extension type and length bytes)
*
* \param ctx Context to use
* \param buf Buffer to write the contents to
* \param len Buffer size
* \param olen Will be updated with the number of bytes written
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successfull,
* a negative error code otherwise
*/
int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx,
unsigned char *buf, size_t len, size_t *olen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Read and process the first round message
* (TLS: contents of the Client/ServerHello extension,
* excluding extension type and length bytes)
*
* \param ctx Context to use
* \param buf Pointer to extension contents
* \param len Extension length
*
* \return 0 if successfull,
* a negative error code otherwise
*/
int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx,
const unsigned char *buf,
size_t len );
/**
* \brief Generate and write the second round message
* (TLS: contents of the Client/ServerKeyExchange)
*
* \param ctx Context to use
* \param buf Buffer to write the contents to
* \param len Buffer size
* \param olen Will be updated with the number of bytes written
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successfull,
* a negative error code otherwise
*/
int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx,
unsigned char *buf, size_t len, size_t *olen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Read and process the second round message
* (TLS: contents of the Client/ServerKeyExchange)
*
* \param ctx Context to use
* \param buf Pointer to the message
* \param len Message length
*
* \return 0 if successfull,
* a negative error code otherwise
*/
int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx,
const unsigned char *buf,
size_t len );
/**
* \brief Derive the shared secret
* (TLS: Pre-Master Secret)
*
* \param ctx Context to use
* \param buf Buffer to write the contents to
* \param len Buffer size
* \param olen Will be updated with the number of bytes written
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successfull,
* a negative error code otherwise
*/
int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx,
unsigned char *buf, size_t len, size_t *olen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Free a context's content
*
* \param ctx context to free
*/
void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx );
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if a test failed
*/
int mbedtls_ecjpake_self_test( int verbose );
#endif
#ifdef __cplusplus
}
#endif
#endif /* ecjpake.h */

View file

@ -0,0 +1,669 @@
/**
* \file ecp.h
*
* \brief Elliptic curves over GF(p)
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_ECP_H
#define MBEDTLS_ECP_H
#include "bignum.h"
/*
* ECP error codes
*/
#define MBEDTLS_ERR_ECP_BAD_INPUT_DATA -0x4F80 /**< Bad input parameters to function. */
#define MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL -0x4F00 /**< The buffer is too small to write to. */
#define MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE -0x4E80 /**< Requested curve not available. */
#define MBEDTLS_ERR_ECP_VERIFY_FAILED -0x4E00 /**< The signature is not valid. */
#define MBEDTLS_ERR_ECP_ALLOC_FAILED -0x4D80 /**< Memory allocation failed. */
#define MBEDTLS_ERR_ECP_RANDOM_FAILED -0x4D00 /**< Generation of random value, such as (ephemeral) key, failed. */
#define MBEDTLS_ERR_ECP_INVALID_KEY -0x4C80 /**< Invalid private or public key. */
#define MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH -0x4C00 /**< Signature is valid but shorter than the user-supplied length. */
#ifdef __cplusplus
extern "C" {
#endif
/**
* Domain parameters (curve, subgroup and generator) identifiers.
*
* Only curves over prime fields are supported.
*
* \warning This library does not support validation of arbitrary domain
* parameters. Therefore, only well-known domain parameters from trusted
* sources should be used. See mbedtls_ecp_group_load().
*/
typedef enum
{
MBEDTLS_ECP_DP_NONE = 0,
MBEDTLS_ECP_DP_SECP192R1, /*!< 192-bits NIST curve */
MBEDTLS_ECP_DP_SECP224R1, /*!< 224-bits NIST curve */
MBEDTLS_ECP_DP_SECP256R1, /*!< 256-bits NIST curve */
MBEDTLS_ECP_DP_SECP384R1, /*!< 384-bits NIST curve */
MBEDTLS_ECP_DP_SECP521R1, /*!< 521-bits NIST curve */
MBEDTLS_ECP_DP_BP256R1, /*!< 256-bits Brainpool curve */
MBEDTLS_ECP_DP_BP384R1, /*!< 384-bits Brainpool curve */
MBEDTLS_ECP_DP_BP512R1, /*!< 512-bits Brainpool curve */
MBEDTLS_ECP_DP_CURVE25519, /*!< Curve25519 */
MBEDTLS_ECP_DP_SECP192K1, /*!< 192-bits "Koblitz" curve */
MBEDTLS_ECP_DP_SECP224K1, /*!< 224-bits "Koblitz" curve */
MBEDTLS_ECP_DP_SECP256K1, /*!< 256-bits "Koblitz" curve */
} mbedtls_ecp_group_id;
/**
* Number of supported curves (plus one for NONE).
*
* (Montgomery curves excluded for now.)
*/
#define MBEDTLS_ECP_DP_MAX 12
/**
* Curve information for use by other modules
*/
typedef struct
{
mbedtls_ecp_group_id grp_id; /*!< Internal identifier */
uint16_t tls_id; /*!< TLS NamedCurve identifier */
uint16_t bit_size; /*!< Curve size in bits */
const char *name; /*!< Human-friendly name */
} mbedtls_ecp_curve_info;
/**
* \brief ECP point structure (jacobian coordinates)
*
* \note All functions expect and return points satisfying
* the following condition: Z == 0 or Z == 1. (Other
* values of Z are used by internal functions only.)
* The point is zero, or "at infinity", if Z == 0.
* Otherwise, X and Y are its standard (affine) coordinates.
*/
typedef struct
{
mbedtls_mpi X; /*!< the point's X coordinate */
mbedtls_mpi Y; /*!< the point's Y coordinate */
mbedtls_mpi Z; /*!< the point's Z coordinate */
}
mbedtls_ecp_point;
/**
* \brief ECP group structure
*
* We consider two types of curves equations:
* 1. Short Weierstrass y^2 = x^3 + A x + B mod P (SEC1 + RFC 4492)
* 2. Montgomery, y^2 = x^3 + A x^2 + x mod P (Curve25519 + draft)
* In both cases, a generator G for a prime-order subgroup is fixed. In the
* short weierstrass, this subgroup is actually the whole curve, and its
* cardinal is denoted by N.
*
* In the case of Short Weierstrass curves, our code requires that N is an odd
* prime. (Use odd in mbedtls_ecp_mul() and prime in mbedtls_ecdsa_sign() for blinding.)
*
* In the case of Montgomery curves, we don't store A but (A + 2) / 4 which is
* the quantity actually used in the formulas. Also, nbits is not the size of N
* but the required size for private keys.
*
* If modp is NULL, reduction modulo P is done using a generic algorithm.
* Otherwise, it must point to a function that takes an mbedtls_mpi in the range
* 0..2^(2*pbits)-1 and transforms it in-place in an integer of little more
* than pbits, so that the integer may be efficiently brought in the 0..P-1
* range by a few additions or substractions. It must return 0 on success and
* non-zero on failure.
*/
typedef struct
{
mbedtls_ecp_group_id id; /*!< internal group identifier */
mbedtls_mpi P; /*!< prime modulus of the base field */
mbedtls_mpi A; /*!< 1. A in the equation, or 2. (A + 2) / 4 */
mbedtls_mpi B; /*!< 1. B in the equation, or 2. unused */
mbedtls_ecp_point G; /*!< generator of the (sub)group used */
mbedtls_mpi N; /*!< 1. the order of G, or 2. unused */
size_t pbits; /*!< number of bits in P */
size_t nbits; /*!< number of bits in 1. P, or 2. private keys */
unsigned int h; /*!< internal: 1 if the constants are static */
int (*modp)(mbedtls_mpi *); /*!< function for fast reduction mod P */
int (*t_pre)(mbedtls_ecp_point *, void *); /*!< unused */
int (*t_post)(mbedtls_ecp_point *, void *); /*!< unused */
void *t_data; /*!< unused */
mbedtls_ecp_point *T; /*!< pre-computed points for ecp_mul_comb() */
size_t T_size; /*!< number for pre-computed points */
}
mbedtls_ecp_group;
/**
* \brief ECP key pair structure
*
* A generic key pair that could be used for ECDSA, fixed ECDH, etc.
*
* \note Members purposefully in the same order as struc mbedtls_ecdsa_context.
*/
typedef struct
{
mbedtls_ecp_group grp; /*!< Elliptic curve and base point */
mbedtls_mpi d; /*!< our secret value */
mbedtls_ecp_point Q; /*!< our public value */
}
mbedtls_ecp_keypair;
/**
* \name SECTION: Module settings
*
* The configuration options you can set for this module are in this section.
* Either change them in config.h or define them on the compiler command line.
* \{
*/
#if !defined(MBEDTLS_ECP_MAX_BITS)
/**
* Maximum size of the groups (that is, of N and P)
*/
#define MBEDTLS_ECP_MAX_BITS 521 /**< Maximum bit size of groups */
#endif
#define MBEDTLS_ECP_MAX_BYTES ( ( MBEDTLS_ECP_MAX_BITS + 7 ) / 8 )
#define MBEDTLS_ECP_MAX_PT_LEN ( 2 * MBEDTLS_ECP_MAX_BYTES + 1 )
#if !defined(MBEDTLS_ECP_WINDOW_SIZE)
/*
* Maximum "window" size used for point multiplication.
* Default: 6.
* Minimum value: 2. Maximum value: 7.
*
* Result is an array of at most ( 1 << ( MBEDTLS_ECP_WINDOW_SIZE - 1 ) )
* points used for point multiplication. This value is directly tied to EC
* peak memory usage, so decreasing it by one should roughly cut memory usage
* by two (if large curves are in use).
*
* Reduction in size may reduce speed, but larger curves are impacted first.
* Sample performances (in ECDHE handshakes/s, with FIXED_POINT_OPTIM = 1):
* w-size: 6 5 4 3 2
* 521 145 141 135 120 97
* 384 214 209 198 177 146
* 256 320 320 303 262 226
* 224 475 475 453 398 342
* 192 640 640 633 587 476
*/
#define MBEDTLS_ECP_WINDOW_SIZE 6 /**< Maximum window size used */
#endif /* MBEDTLS_ECP_WINDOW_SIZE */
#if !defined(MBEDTLS_ECP_FIXED_POINT_OPTIM)
/*
* Trade memory for speed on fixed-point multiplication.
*
* This speeds up repeated multiplication of the generator (that is, the
* multiplication in ECDSA signatures, and half of the multiplications in
* ECDSA verification and ECDHE) by a factor roughly 3 to 4.
*
* The cost is increasing EC peak memory usage by a factor roughly 2.
*
* Change this value to 0 to reduce peak memory usage.
*/
#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */
#endif /* MBEDTLS_ECP_FIXED_POINT_OPTIM */
/* \} name SECTION: Module settings */
/*
* Point formats, from RFC 4492's enum ECPointFormat
*/
#define MBEDTLS_ECP_PF_UNCOMPRESSED 0 /**< Uncompressed point format */
#define MBEDTLS_ECP_PF_COMPRESSED 1 /**< Compressed point format */
/*
* Some other constants from RFC 4492
*/
#define MBEDTLS_ECP_TLS_NAMED_CURVE 3 /**< ECCurveType's named_curve */
/**
* \brief Get the list of supported curves in order of preferrence
* (full information)
*
* \return A statically allocated array, the last entry is 0.
*/
const mbedtls_ecp_curve_info *mbedtls_ecp_curve_list( void );
/**
* \brief Get the list of supported curves in order of preferrence
* (grp_id only)
*
* \return A statically allocated array,
* terminated with MBEDTLS_ECP_DP_NONE.
*/
const mbedtls_ecp_group_id *mbedtls_ecp_grp_id_list( void );
/**
* \brief Get curve information from an internal group identifier
*
* \param grp_id A MBEDTLS_ECP_DP_XXX value
*
* \return The associated curve information or NULL
*/
const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_grp_id( mbedtls_ecp_group_id grp_id );
/**
* \brief Get curve information from a TLS NamedCurve value
*
* \param tls_id A MBEDTLS_ECP_DP_XXX value
*
* \return The associated curve information or NULL
*/
const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_tls_id( uint16_t tls_id );
/**
* \brief Get curve information from a human-readable name
*
* \param name The name
*
* \return The associated curve information or NULL
*/
const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_name( const char *name );
/**
* \brief Initialize a point (as zero)
*/
void mbedtls_ecp_point_init( mbedtls_ecp_point *pt );
/**
* \brief Initialize a group (to something meaningless)
*/
void mbedtls_ecp_group_init( mbedtls_ecp_group *grp );
/**
* \brief Initialize a key pair (as an invalid one)
*/
void mbedtls_ecp_keypair_init( mbedtls_ecp_keypair *key );
/**
* \brief Free the components of a point
*/
void mbedtls_ecp_point_free( mbedtls_ecp_point *pt );
/**
* \brief Free the components of an ECP group
*/
void mbedtls_ecp_group_free( mbedtls_ecp_group *grp );
/**
* \brief Free the components of a key pair
*/
void mbedtls_ecp_keypair_free( mbedtls_ecp_keypair *key );
/**
* \brief Copy the contents of point Q into P
*
* \param P Destination point
* \param Q Source point
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_ecp_copy( mbedtls_ecp_point *P, const mbedtls_ecp_point *Q );
/**
* \brief Copy the contents of a group object
*
* \param dst Destination group
* \param src Source group
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst, const mbedtls_ecp_group *src );
/**
* \brief Set a point to zero
*
* \param pt Destination point
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_ecp_set_zero( mbedtls_ecp_point *pt );
/**
* \brief Tell if a point is zero
*
* \param pt Point to test
*
* \return 1 if point is zero, 0 otherwise
*/
int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt );
/**
* \brief Compare two points
*
* \note This assumes the points are normalized. Otherwise,
* they may compare as "not equal" even if they are.
*
* \param P First point to compare
* \param Q Second point to compare
*
* \return 0 if the points are equal,
* MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise
*/
int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P,
const mbedtls_ecp_point *Q );
/**
* \brief Import a non-zero point from two ASCII strings
*
* \param P Destination point
* \param radix Input numeric base
* \param x First affine coordinate as a null-terminated string
* \param y Second affine coordinate as a null-terminated string
*
* \return 0 if successful, or a MBEDTLS_ERR_MPI_XXX error code
*/
int mbedtls_ecp_point_read_string( mbedtls_ecp_point *P, int radix,
const char *x, const char *y );
/**
* \brief Export a point into unsigned binary data
*
* \param grp Group to which the point should belong
* \param P Point to export
* \param format Point format, should be a MBEDTLS_ECP_PF_XXX macro
* \param olen Length of the actual output
* \param buf Output buffer
* \param buflen Length of the output buffer
*
* \return 0 if successful,
* or MBEDTLS_ERR_ECP_BAD_INPUT_DATA
* or MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
*/
int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *P,
int format, size_t *olen,
unsigned char *buf, size_t buflen );
/**
* \brief Import a point from unsigned binary data
*
* \param grp Group to which the point should belong
* \param P Point to import
* \param buf Input buffer
* \param ilen Actual length of input
*
* \return 0 if successful,
* MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
* MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format
* is not implemented.
*
* \note This function does NOT check that the point actually
* belongs to the given group, see mbedtls_ecp_check_pubkey() for
* that.
*/
int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P,
const unsigned char *buf, size_t ilen );
/**
* \brief Import a point from a TLS ECPoint record
*
* \param grp ECP group used
* \param pt Destination point
* \param buf $(Start of input buffer)
* \param len Buffer length
*
* \note buf is updated to point right after the ECPoint on exit
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_XXX if initialization failed
* MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid
*/
int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt,
const unsigned char **buf, size_t len );
/**
* \brief Export a point as a TLS ECPoint record
*
* \param grp ECP group used
* \param pt Point to export
* \param format Export format
* \param olen length of data written
* \param buf Buffer to write to
* \param blen Buffer length
*
* \return 0 if successful,
* or MBEDTLS_ERR_ECP_BAD_INPUT_DATA
* or MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
*/
int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt,
int format, size_t *olen,
unsigned char *buf, size_t blen );
/**
* \brief Set a group using well-known domain parameters
*
* \param grp Destination group
* \param index Index in the list of well-known domain parameters
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_XXX if initialization failed
* MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE for unkownn groups
*
* \note Index should be a value of RFC 4492's enum NamedCurve,
* usually in the form of a MBEDTLS_ECP_DP_XXX macro.
*/
int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id index );
/**
* \brief Set a group from a TLS ECParameters record
*
* \param grp Destination group
* \param buf &(Start of input buffer)
* \param len Buffer length
*
* \note buf is updated to point right after ECParameters on exit
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_XXX if initialization failed
* MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid
*/
int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp, const unsigned char **buf, size_t len );
/**
* \brief Write the TLS ECParameters record for a group
*
* \param grp ECP group used
* \param olen Number of bytes actually written
* \param buf Buffer to write to
* \param blen Buffer length
*
* \return 0 if successful,
* or MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
*/
int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, size_t *olen,
unsigned char *buf, size_t blen );
/**
* \brief Multiplication by an integer: R = m * P
* (Not thread-safe to use same group in multiple threads)
*
* \note In order to prevent timing attacks, this function
* executes the exact same sequence of (base field)
* operations for any valid m. It avoids any if-branch or
* array index depending on the value of m.
*
* \note If f_rng is not NULL, it is used to randomize intermediate
* results in order to prevent potential timing attacks
* targeting these results. It is recommended to always
* provide a non-NULL f_rng (the overhead is negligible).
*
* \param grp ECP group
* \param R Destination point
* \param m Integer by which to multiply
* \param P Point to multiply
* \param f_rng RNG function (see notes)
* \param p_rng RNG parameter
*
* \return 0 if successful,
* MBEDTLS_ERR_ECP_INVALID_KEY if m is not a valid privkey
* or P is not a valid pubkey,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
const mbedtls_mpi *m, const mbedtls_ecp_point *P,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
/**
* \brief Multiplication and addition of two points by integers:
* R = m * P + n * Q
* (Not thread-safe to use same group in multiple threads)
*
* \note In contrast to mbedtls_ecp_mul(), this function does not guarantee
* a constant execution flow and timing.
*
* \param grp ECP group
* \param R Destination point
* \param m Integer by which to multiply P
* \param P Point to multiply by m
* \param n Integer by which to multiply Q
* \param Q Point to be multiplied by n
*
* \return 0 if successful,
* MBEDTLS_ERR_ECP_INVALID_KEY if m or n is not a valid privkey
* or P or Q is not a valid pubkey,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
const mbedtls_mpi *m, const mbedtls_ecp_point *P,
const mbedtls_mpi *n, const mbedtls_ecp_point *Q );
/**
* \brief Check that a point is a valid public key on this curve
*
* \param grp Curve/group the point should belong to
* \param pt Point to check
*
* \return 0 if point is a valid public key,
* MBEDTLS_ERR_ECP_INVALID_KEY otherwise.
*
* \note This function only checks the point is non-zero, has valid
* coordinates and lies on the curve, but not that it is
* indeed a multiple of G. This is additional check is more
* expensive, isn't required by standards, and shouldn't be
* necessary if the group used has a small cofactor. In
* particular, it is useless for the NIST groups which all
* have a cofactor of 1.
*
* \note Uses bare components rather than an mbedtls_ecp_keypair structure
* in order to ease use with other structures such as
* mbedtls_ecdh_context of mbedtls_ecdsa_context.
*/
int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt );
/**
* \brief Check that an mbedtls_mpi is a valid private key for this curve
*
* \param grp Group used
* \param d Integer to check
*
* \return 0 if point is a valid private key,
* MBEDTLS_ERR_ECP_INVALID_KEY otherwise.
*
* \note Uses bare components rather than an mbedtls_ecp_keypair structure
* in order to ease use with other structures such as
* mbedtls_ecdh_context of mbedtls_ecdsa_context.
*/
int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, const mbedtls_mpi *d );
/**
* \brief Generate a keypair with configurable base point
*
* \param grp ECP group
* \param G Chosen base point
* \param d Destination MPI (secret part)
* \param Q Destination point (public part)
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successful,
* or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code
*
* \note Uses bare components rather than an mbedtls_ecp_keypair structure
* in order to ease use with other structures such as
* mbedtls_ecdh_context of mbedtls_ecdsa_context.
*/
int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp,
const mbedtls_ecp_point *G,
mbedtls_mpi *d, mbedtls_ecp_point *Q,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Generate a keypair
*
* \param grp ECP group
* \param d Destination MPI (secret part)
* \param Q Destination point (public part)
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successful,
* or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code
*
* \note Uses bare components rather than an mbedtls_ecp_keypair structure
* in order to ease use with other structures such as
* mbedtls_ecdh_context of mbedtls_ecdsa_context.
*/
int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Generate a keypair
*
* \param grp_id ECP group identifier
* \param key Destination keypair
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successful,
* or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code
*/
int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
/**
* \brief Check a public-private key pair
*
* \param pub Keypair structure holding a public key
* \param prv Keypair structure holding a private (plus public) key
*
* \return 0 if successful (keys are valid and match), or
* MBEDTLS_ERR_ECP_BAD_INPUT_DATA, or
* a MBEDTLS_ERR_ECP_XXX or MBEDTLS_ERR_MPI_XXX code.
*/
int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv );
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if a test failed
*/
int mbedtls_ecp_self_test( int verbose );
#endif
#ifdef __cplusplus
}
#endif
#endif /* ecp.h */

View file

@ -0,0 +1,287 @@
/**
* \file entropy.h
*
* \brief Entropy accumulator implementation
*
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_ENTROPY_H
#define MBEDTLS_ENTROPY_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256)
#include "sha512.h"
#define MBEDTLS_ENTROPY_SHA512_ACCUMULATOR
#else
#if defined(MBEDTLS_SHA256_C)
#define MBEDTLS_ENTROPY_SHA256_ACCUMULATOR
#include "sha256.h"
#endif
#endif
#if defined(MBEDTLS_THREADING_C)
#include "threading.h"
#endif
#if defined(MBEDTLS_HAVEGE_C)
#include "havege.h"
#endif
#define MBEDTLS_ERR_ENTROPY_SOURCE_FAILED -0x003C /**< Critical entropy source failure. */
#define MBEDTLS_ERR_ENTROPY_MAX_SOURCES -0x003E /**< No more sources can be added. */
#define MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED -0x0040 /**< No sources have been added to poll. */
#define MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE -0x003D /**< No strong sources have been added to poll. */
#define MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR -0x003F /**< Read/write error in file. */
/**
* \name SECTION: Module settings
*
* The configuration options you can set for this module are in this section.
* Either change them in config.h or define them on the compiler command line.
* \{
*/
#if !defined(MBEDTLS_ENTROPY_MAX_SOURCES)
#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */
#endif
#if !defined(MBEDTLS_ENTROPY_MAX_GATHER)
#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */
#endif
/* \} name SECTION: Module settings */
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
#define MBEDTLS_ENTROPY_BLOCK_SIZE 64 /**< Block size of entropy accumulator (SHA-512) */
#else
#define MBEDTLS_ENTROPY_BLOCK_SIZE 32 /**< Block size of entropy accumulator (SHA-256) */
#endif
#define MBEDTLS_ENTROPY_MAX_SEED_SIZE 1024 /**< Maximum size of seed we read from seed file */
#define MBEDTLS_ENTROPY_SOURCE_MANUAL MBEDTLS_ENTROPY_MAX_SOURCES
#define MBEDTLS_ENTROPY_SOURCE_STRONG 1 /**< Entropy source is strong */
#define MBEDTLS_ENTROPY_SOURCE_WEAK 0 /**< Entropy source is weak */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Entropy poll callback pointer
*
* \param data Callback-specific data pointer
* \param output Data to fill
* \param len Maximum size to provide
* \param olen The actual amount of bytes put into the buffer (Can be 0)
*
* \return 0 if no critical failures occurred,
* MBEDTLS_ERR_ENTROPY_SOURCE_FAILED otherwise
*/
typedef int (*mbedtls_entropy_f_source_ptr)(void *data, unsigned char *output, size_t len,
size_t *olen);
/**
* \brief Entropy source state
*/
typedef struct
{
mbedtls_entropy_f_source_ptr f_source; /**< The entropy source callback */
void * p_source; /**< The callback data pointer */
size_t size; /**< Amount received in bytes */
size_t threshold; /**< Minimum bytes required before release */
int strong; /**< Is the source strong? */
}
mbedtls_entropy_source_state;
/**
* \brief Entropy context structure
*/
typedef struct
{
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
mbedtls_sha512_context accumulator;
#else
mbedtls_sha256_context accumulator;
#endif
int source_count;
mbedtls_entropy_source_state source[MBEDTLS_ENTROPY_MAX_SOURCES];
#if defined(MBEDTLS_HAVEGE_C)
mbedtls_havege_state havege_data;
#endif
#if defined(MBEDTLS_THREADING_C)
mbedtls_threading_mutex_t mutex; /*!< mutex */
#endif
#if defined(MBEDTLS_ENTROPY_NV_SEED)
int initial_entropy_run;
#endif
}
mbedtls_entropy_context;
/**
* \brief Initialize the context
*
* \param ctx Entropy context to initialize
*/
void mbedtls_entropy_init( mbedtls_entropy_context *ctx );
/**
* \brief Free the data in the context
*
* \param ctx Entropy context to free
*/
void mbedtls_entropy_free( mbedtls_entropy_context *ctx );
/**
* \brief Adds an entropy source to poll
* (Thread-safe if MBEDTLS_THREADING_C is enabled)
*
* \param ctx Entropy context
* \param f_source Entropy function
* \param p_source Function data
* \param threshold Minimum required from source before entropy is released
* ( with mbedtls_entropy_func() ) (in bytes)
* \param strong MBEDTLS_ENTROPY_SOURCE_STRONG or
* MBEDTSL_ENTROPY_SOURCE_WEAK.
* At least one strong source needs to be added.
* Weaker sources (such as the cycle counter) can be used as
* a complement.
*
* \return 0 if successful or MBEDTLS_ERR_ENTROPY_MAX_SOURCES
*/
int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx,
mbedtls_entropy_f_source_ptr f_source, void *p_source,
size_t threshold, int strong );
/**
* \brief Trigger an extra gather poll for the accumulator
* (Thread-safe if MBEDTLS_THREADING_C is enabled)
*
* \param ctx Entropy context
*
* \return 0 if successful, or MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
*/
int mbedtls_entropy_gather( mbedtls_entropy_context *ctx );
/**
* \brief Retrieve entropy from the accumulator
* (Maximum length: MBEDTLS_ENTROPY_BLOCK_SIZE)
* (Thread-safe if MBEDTLS_THREADING_C is enabled)
*
* \param data Entropy context
* \param output Buffer to fill
* \param len Number of bytes desired, must be at most MBEDTLS_ENTROPY_BLOCK_SIZE
*
* \return 0 if successful, or MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
*/
int mbedtls_entropy_func( void *data, unsigned char *output, size_t len );
/**
* \brief Add data to the accumulator manually
* (Thread-safe if MBEDTLS_THREADING_C is enabled)
*
* \param ctx Entropy context
* \param data Data to add
* \param len Length of data
*
* \return 0 if successful
*/
int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx,
const unsigned char *data, size_t len );
#if defined(MBEDTLS_ENTROPY_NV_SEED)
/**
* \brief Trigger an update of the seed file in NV by using the
* current entropy pool.
*
* \param ctx Entropy context
*
* \return 0 if successful
*/
int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx );
#endif /* MBEDTLS_ENTROPY_NV_SEED */
#if defined(MBEDTLS_FS_IO)
/**
* \brief Write a seed file
*
* \param ctx Entropy context
* \param path Name of the file
*
* \return 0 if successful,
* MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR on file error, or
* MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
*/
int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *path );
/**
* \brief Read and update a seed file. Seed is added to this
* instance. No more than MBEDTLS_ENTROPY_MAX_SEED_SIZE bytes are
* read from the seed file. The rest is ignored.
*
* \param ctx Entropy context
* \param path Name of the file
*
* \return 0 if successful,
* MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR on file error,
* MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
*/
int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char *path );
#endif /* MBEDTLS_FS_IO */
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
* This module self-test also calls the entropy self-test,
* mbedtls_entropy_source_self_test();
*
* \return 0 if successful, or 1 if a test failed
*/
int mbedtls_entropy_self_test( int verbose );
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
/**
* \brief Checkup routine
*
* Verifies the integrity of the hardware entropy source
* provided by the function 'mbedtls_hardware_poll()'.
*
* Note this is the only hardware entropy source that is known
* at link time, and other entropy sources configured
* dynamically at runtime by the function
* mbedtls_entropy_add_source() will not be tested.
*
* \return 0 if successful, or 1 if a test failed
*/
int mbedtls_entropy_source_self_test( int verbose );
#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */
#endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus
}
#endif
#endif /* entropy.h */

View file

@ -0,0 +1,109 @@
/**
* \file entropy_poll.h
*
* \brief Platform-specific and custom entropy polling functions
*
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_ENTROPY_POLL_H
#define MBEDTLS_ENTROPY_POLL_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* Default thresholds for built-in sources, in bytes
*/
#define MBEDTLS_ENTROPY_MIN_PLATFORM 32 /**< Minimum for platform source */
#define MBEDTLS_ENTROPY_MIN_HAVEGE 32 /**< Minimum for HAVEGE */
#define MBEDTLS_ENTROPY_MIN_HARDCLOCK 4 /**< Minimum for mbedtls_timing_hardclock() */
#if !defined(MBEDTLS_ENTROPY_MIN_HARDWARE)
#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Minimum for the hardware source */
#endif
/**
* \brief Entropy poll callback that provides 0 entropy.
*/
#if defined(MBEDTLS_TEST_NULL_ENTROPY)
int mbedtls_null_entropy_poll( void *data,
unsigned char *output, size_t len, size_t *olen );
#endif
#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
/**
* \brief Platform-specific entropy poll callback
*/
int mbedtls_platform_entropy_poll( void *data,
unsigned char *output, size_t len, size_t *olen );
#endif
#if defined(MBEDTLS_HAVEGE_C)
/**
* \brief HAVEGE based entropy poll callback
*
* Requires an HAVEGE state as its data pointer.
*/
int mbedtls_havege_poll( void *data,
unsigned char *output, size_t len, size_t *olen );
#endif
#if defined(MBEDTLS_TIMING_C)
/**
* \brief mbedtls_timing_hardclock-based entropy poll callback
*/
int mbedtls_hardclock_poll( void *data,
unsigned char *output, size_t len, size_t *olen );
#endif
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
/**
* \brief Entropy poll callback for a hardware source
*
* \warning This is not provided by mbed TLS!
* See \c MBEDTLS_ENTROPY_HARDWARE_ALT in config.h.
*
* \note This must accept NULL as its first argument.
*/
int mbedtls_hardware_poll( void *data,
unsigned char *output, size_t len, size_t *olen );
#endif
#if defined(MBEDTLS_ENTROPY_NV_SEED)
/**
* \brief Entropy poll callback for a non-volatile seed file
*
* \note This must accept NULL as its first argument.
*/
int mbedtls_nv_seed_poll( void *data,
unsigned char *output, size_t len, size_t *olen );
#endif
#ifdef __cplusplus
}
#endif
#endif /* entropy_poll.h */

View file

@ -0,0 +1,107 @@
/**
* \file error.h
*
* \brief Error to string translation
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_ERROR_H
#define MBEDTLS_ERROR_H
#include <stddef.h>
/**
* Error code layout.
*
* Currently we try to keep all error codes within the negative space of 16
* bits signed integers to support all platforms (-0x0001 - -0x7FFF). In
* addition we'd like to give two layers of information on the error if
* possible.
*
* For that purpose the error codes are segmented in the following manner:
*
* 16 bit error code bit-segmentation
*
* 1 bit - Unused (sign bit)
* 3 bits - High level module ID
* 5 bits - Module-dependent error code
* 7 bits - Low level module errors
*
* For historical reasons, low-level error codes are divided in even and odd,
* even codes were assigned first, and -1 is reserved for other errors.
*
* Low-level module errors (0x0002-0x007E, 0x0003-0x007F)
*
* Module Nr Codes assigned
* MPI 7 0x0002-0x0010
* GCM 2 0x0012-0x0014
* BLOWFISH 2 0x0016-0x0018
* THREADING 3 0x001A-0x001E
* AES 2 0x0020-0x0022
* CAMELLIA 2 0x0024-0x0026
* XTEA 1 0x0028-0x0028
* BASE64 2 0x002A-0x002C
* OID 1 0x002E-0x002E 0x000B-0x000B
* PADLOCK 1 0x0030-0x0030
* DES 1 0x0032-0x0032
* CTR_DBRG 4 0x0034-0x003A
* ENTROPY 3 0x003C-0x0040 0x003D-0x003F
* NET 11 0x0042-0x0052 0x0043-0x0045
* ASN1 7 0x0060-0x006C
* PBKDF2 1 0x007C-0x007C
* HMAC_DRBG 4 0x0003-0x0009
* CCM 2 0x000D-0x000F
*
* High-level module nr (3 bits - 0x0...-0x7...)
* Name ID Nr of Errors
* PEM 1 9
* PKCS#12 1 4 (Started from top)
* X509 2 19
* PKCS5 2 4 (Started from top)
* DHM 3 9
* PK 3 14 (Started from top)
* RSA 4 9
* ECP 4 8 (Started from top)
* MD 5 4
* CIPHER 6 6
* SSL 6 17 (Started from top)
* SSL 7 31
*
* Module dependent error code (5 bits 0x.00.-0x.F8.)
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Translate a mbed TLS error code into a string representation,
* Result is truncated if necessary and always includes a terminating
* null byte.
*
* \param errnum error code
* \param buffer buffer to place representation in
* \param buflen length of the buffer
*/
void mbedtls_strerror( int errnum, char *buffer, size_t buflen );
#ifdef __cplusplus
}
#endif
#endif /* error.h */

View file

@ -0,0 +1,220 @@
/**
* \file gcm.h
*
* \brief Galois/Counter mode for 128-bit block ciphers
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_GCM_H
#define MBEDTLS_GCM_H
#include "cipher.h"
#include <stdint.h>
#define MBEDTLS_GCM_ENCRYPT 1
#define MBEDTLS_GCM_DECRYPT 0
#define MBEDTLS_ERR_GCM_AUTH_FAILED -0x0012 /**< Authenticated decryption failed. */
#define MBEDTLS_ERR_GCM_BAD_INPUT -0x0014 /**< Bad input parameters to function. */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief GCM context structure
*/
typedef struct {
mbedtls_cipher_context_t cipher_ctx;/*!< cipher context used */
uint64_t HL[16]; /*!< Precalculated HTable */
uint64_t HH[16]; /*!< Precalculated HTable */
uint64_t len; /*!< Total data length */
uint64_t add_len; /*!< Total add length */
unsigned char base_ectr[16];/*!< First ECTR for tag */
unsigned char y[16]; /*!< Y working value */
unsigned char buf[16]; /*!< buf working value */
int mode; /*!< Encrypt or Decrypt */
}
mbedtls_gcm_context;
/**
* \brief Initialize GCM context (just makes references valid)
* Makes the context ready for mbedtls_gcm_setkey() or
* mbedtls_gcm_free().
*
* \param ctx GCM context to initialize
*/
void mbedtls_gcm_init( mbedtls_gcm_context *ctx );
/**
* \brief GCM initialization (encryption)
*
* \param ctx GCM context to be initialized
* \param cipher cipher to use (a 128-bit block cipher)
* \param key encryption key
* \param keybits must be 128, 192 or 256
*
* \return 0 if successful, or a cipher specific error code
*/
int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
mbedtls_cipher_id_t cipher,
const unsigned char *key,
unsigned int keybits );
/**
* \brief GCM buffer encryption/decryption using a block cipher
*
* \note On encryption, the output buffer can be the same as the input buffer.
* On decryption, the output buffer cannot be the same as input buffer.
* If buffers overlap, the output buffer must trail at least 8 bytes
* behind the input buffer.
*
* \param ctx GCM context
* \param mode MBEDTLS_GCM_ENCRYPT or MBEDTLS_GCM_DECRYPT
* \param length length of the input data
* \param iv initialization vector
* \param iv_len length of IV
* \param add additional data
* \param add_len length of additional data
* \param input buffer holding the input data
* \param output buffer for holding the output data
* \param tag_len length of the tag to generate
* \param tag buffer for holding the tag
*
* \return 0 if successful
*/
int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
int mode,
size_t length,
const unsigned char *iv,
size_t iv_len,
const unsigned char *add,
size_t add_len,
const unsigned char *input,
unsigned char *output,
size_t tag_len,
unsigned char *tag );
/**
* \brief GCM buffer authenticated decryption using a block cipher
*
* \note On decryption, the output buffer cannot be the same as input buffer.
* If buffers overlap, the output buffer must trail at least 8 bytes
* behind the input buffer.
*
* \param ctx GCM context
* \param length length of the input data
* \param iv initialization vector
* \param iv_len length of IV
* \param add additional data
* \param add_len length of additional data
* \param tag buffer holding the tag
* \param tag_len length of the tag
* \param input buffer holding the input data
* \param output buffer for holding the output data
*
* \return 0 if successful and authenticated,
* MBEDTLS_ERR_GCM_AUTH_FAILED if tag does not match
*/
int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
size_t length,
const unsigned char *iv,
size_t iv_len,
const unsigned char *add,
size_t add_len,
const unsigned char *tag,
size_t tag_len,
const unsigned char *input,
unsigned char *output );
/**
* \brief Generic GCM stream start function
*
* \param ctx GCM context
* \param mode MBEDTLS_GCM_ENCRYPT or MBEDTLS_GCM_DECRYPT
* \param iv initialization vector
* \param iv_len length of IV
* \param add additional data (or NULL if length is 0)
* \param add_len length of additional data
*
* \return 0 if successful
*/
int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
int mode,
const unsigned char *iv,
size_t iv_len,
const unsigned char *add,
size_t add_len );
/**
* \brief Generic GCM update function. Encrypts/decrypts using the
* given GCM context. Expects input to be a multiple of 16
* bytes! Only the last call before mbedtls_gcm_finish() can be less
* than 16 bytes!
*
* \note On decryption, the output buffer cannot be the same as input buffer.
* If buffers overlap, the output buffer must trail at least 8 bytes
* behind the input buffer.
*
* \param ctx GCM context
* \param length length of the input data
* \param input buffer holding the input data
* \param output buffer for holding the output data
*
* \return 0 if successful or MBEDTLS_ERR_GCM_BAD_INPUT
*/
int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
size_t length,
const unsigned char *input,
unsigned char *output );
/**
* \brief Generic GCM finalisation function. Wraps up the GCM stream
* and generates the tag. The tag can have a maximum length of
* 16 bytes.
*
* \param ctx GCM context
* \param tag buffer for holding the tag
* \param tag_len length of the tag to generate (must be at least 4)
*
* \return 0 if successful or MBEDTLS_ERR_GCM_BAD_INPUT
*/
int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
unsigned char *tag,
size_t tag_len );
/**
* \brief Free a GCM context and underlying cipher sub-context
*
* \param ctx GCM context to free
*/
void mbedtls_gcm_free( mbedtls_gcm_context *ctx );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mbedtls_gcm_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* gcm.h */

View file

@ -0,0 +1,181 @@
/**
* \file hash.h
*
* \brief Generic message digest wrapper
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_HASH_H
#define MBEDTLS_HASH_H
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Opaque struct defined in md_internal.h
*/
typedef struct mbedtls_md_info_t mbedtls_hash_info_t;
#define mbedtls_hash_context_t mbedtls_md_context_t
/**
* \brief Returns the message digest information associated with the
* given digest type.
*
* \param md_type type of digest to search for.
*
* \return The message digest information associated with md_type or
* NULL if not found.
*/
const mbedtls_hash_info_t *mbedtls_hash_info_from_type( mbedtls_md_type_t md_type );
/**
* \brief Initialize a md_context (as NONE)
* This should always be called first.
* Prepares the context for mbedtls_md_setup() or mbedtls_md_free().
*/
void mbedtls_hash_init( mbedtls_hash_context_t *ctx );
/**
* \brief Free and clear the internal structures of ctx.
* Can be called at any time after mbedtls_hash_init().
* Mandatory once mbedtls_md_setup() has been called.
*/
void mbedtls_hash_free( mbedtls_hash_context_t *ctx );
#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief Select MD to use and allocate internal structures.
* Should be called after mbedtls_md_init() or mbedtls_md_free().
* Makes it necessary to call mbedtls_md_free() later.
*
* \deprecated Superseded by mbedtls_md_setup() in 2.0.0
*
* \param ctx Context to set up.
* \param md_info Message digest to use.
*
* \returns \c 0 on success,
* \c MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter failure,
* \c MBEDTLS_ERR_MD_ALLOC_FAILED memory allocation failure.
*/
int mbedtls_hash_init_ctx( mbedtls_hash_context_t *ctx, const mbedtls_hash_info_t *md_info ) MBEDTLS_DEPRECATED;
#undef MBEDTLS_DEPRECATED
#endif /* MBEDTLS_DEPRECATED_REMOVED */
/**
* \brief Select MD to use and allocate internal structures.
* Should be called after mbedtls_md_init() or mbedtls_md_free().
* Makes it necessary to call mbedtls_md_free() later.
*
* \param ctx Context to set up.
* \param md_info Message digest to use.
* \param hmac 0 to save some memory if HMAC will not be used,
* non-zero is HMAC is going to be used with this context.
*
* \returns \c 0 on success,
* \c MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter failure,
* \c MBEDTLS_ERR_MD_ALLOC_FAILED memory allocation failure.
*/
int mbedtls_hash_setup( mbedtls_hash_context_t *ctx, const mbedtls_hash_info_t *md_info, int hmac );
/**
* \brief Returns the size of the message digest output.
*
* \param md_info message digest info
*
* \return size of the message digest output in bytes.
*/
unsigned char mbedtls_hash_get_size( const mbedtls_hash_info_t *md_info );
/**
* \brief Returns the type of the message digest output.
*
* \param md_info message digest info
*
* \return type of the message digest output.
*/
mbedtls_md_type_t mbedtls_hash_get_type( const mbedtls_hash_info_t *md_info );
/**
* \brief Prepare the context to digest a new message.
* Generally called after mbedtls_md_setup() or mbedtls_hash_finish().
* Followed by mbedtls_hash_update().
*
* \param ctx generic message digest context.
*
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int mbedtls_hash_starts( mbedtls_hash_context_t *ctx );
/**
* \brief Generic message digest process buffer
* Called between mbedtls_hash_starts() and mbedtls_hash_finish().
* May be called repeatedly.
*
* \param ctx Generic message digest context
* \param input buffer holding the datal
* \param ilen length of the input data
*
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int mbedtls_hash_update( mbedtls_hash_context_t *ctx, const unsigned char *input, size_t ilen );
/**
* \brief Generic message digest final digest
* Called after mbedtls_hash_update().
* Usually followed by mbedtls_md_free() or mbedtls_hash_starts().
*
* \param ctx Generic message digest context
* \param output Generic message digest checksum result
*
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int mbedtls_hash_finish( mbedtls_hash_context_t *ctx, unsigned char *output );
/**
* \brief Output = message_digest( input buffer )
*
* \param md_info message digest info
* \param input buffer holding the data
* \param ilen length of the input data
* \param output Generic message digest checksum result
*
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int mbedtls_hash( const mbedtls_hash_info_t *md_info, const unsigned char *input, size_t ilen,
unsigned char *output );
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_HASH_H */

View file

@ -0,0 +1,74 @@
/**
* \file havege.h
*
* \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_HAVEGE_H
#define MBEDTLS_HAVEGE_H
#include <stddef.h>
#define MBEDTLS_HAVEGE_COLLECT_SIZE 1024
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief HAVEGE state structure
*/
typedef struct
{
int PT1, PT2, offset[2];
int pool[MBEDTLS_HAVEGE_COLLECT_SIZE];
int WALK[8192];
}
mbedtls_havege_state;
/**
* \brief HAVEGE initialization
*
* \param hs HAVEGE state to be initialized
*/
void mbedtls_havege_init( mbedtls_havege_state *hs );
/**
* \brief Clear HAVEGE state
*
* \param hs HAVEGE state to be cleared
*/
void mbedtls_havege_free( mbedtls_havege_state *hs );
/**
* \brief HAVEGE rand function
*
* \param p_rng A HAVEGE state
* \param output Buffer to fill
* \param len Length of buffer
*
* \return 0
*/
int mbedtls_havege_random( void *p_rng, unsigned char *output, size_t len );
#ifdef __cplusplus
}
#endif
#endif /* havege.h */

View file

@ -0,0 +1,50 @@
/**
* \file hash.h
*
* \brief Generic message digest wrapper
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_HMAC_H
#define MBEDTLS_HMAC_H
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
int mbedtls_hmac_starts( mbedtls_hash_context_t *ctx, const unsigned char *key, size_t keylen );
int mbedtls_hmac_update( mbedtls_hash_context_t *ctx, const unsigned char *input, size_t ilen );
int mbedtls_hmac_finish( mbedtls_hash_context_t *ctx, unsigned char *output );
int mbedtls_hash_hmac( const mbedtls_hash_info_t *md_info, const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char *output );
int mbedtls_hmac_reset( mbedtls_hash_context_t *ctx );
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_HMAC_H */

View file

@ -0,0 +1,299 @@
/**
* \file hmac_drbg.h
*
* \brief HMAC_DRBG (NIST SP 800-90A)
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_HMAC_DRBG_H
#define MBEDTLS_HMAC_DRBG_H
#include "md.h"
#if defined(MBEDTLS_THREADING_C)
#include "mbedtls/threading.h"
#endif
/*
* Error codes
*/
#define MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG -0x0003 /**< Too many random requested in single call. */
#define MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG -0x0005 /**< Input too large (Entropy + additional). */
#define MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR -0x0007 /**< Read/write error in file. */
#define MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED -0x0009 /**< The entropy source failed. */
/**
* \name SECTION: Module settings
*
* The configuration options you can set for this module are in this section.
* Either change them in config.h or define them on the compiler command line.
* \{
*/
#if !defined(MBEDTLS_HMAC_DRBG_RESEED_INTERVAL)
#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */
#endif
#if !defined(MBEDTLS_HMAC_DRBG_MAX_INPUT)
#define MBEDTLS_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */
#endif
#if !defined(MBEDTLS_HMAC_DRBG_MAX_REQUEST)
#define MBEDTLS_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */
#endif
#if !defined(MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT)
#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */
#endif
/* \} name SECTION: Module settings */
#define MBEDTLS_HMAC_DRBG_PR_OFF 0 /**< No prediction resistance */
#define MBEDTLS_HMAC_DRBG_PR_ON 1 /**< Prediction resistance enabled */
#ifdef __cplusplus
extern "C" {
#endif
/**
* HMAC_DRBG context.
*/
typedef struct
{
/* Working state: the key K is not stored explicitely,
* but is implied by the HMAC context */
mbedtls_md_context_t md_ctx; /*!< HMAC context (inc. K) */
unsigned char V[MBEDTLS_MD_MAX_SIZE]; /*!< V in the spec */
int reseed_counter; /*!< reseed counter */
/* Administrative state */
size_t entropy_len; /*!< entropy bytes grabbed on each (re)seed */
int prediction_resistance; /*!< enable prediction resistance (Automatic
reseed before every random generation) */
int reseed_interval; /*!< reseed interval */
/* Callbacks */
int (*f_entropy)(void *, unsigned char *, size_t); /*!< entropy function */
void *p_entropy; /*!< context for the entropy function */
#if defined(MBEDTLS_THREADING_C)
mbedtls_threading_mutex_t mutex;
#endif
} mbedtls_hmac_drbg_context;
/**
* \brief HMAC_DRBG context initialization
* Makes the context ready for mbedtls_hmac_drbg_seed(),
* mbedtls_hmac_drbg_seed_buf() or
* mbedtls_hmac_drbg_free().
*
* \param ctx HMAC_DRBG context to be initialized
*/
void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx );
/**
* \brief HMAC_DRBG initial seeding
* Seed and setup entropy source for future reseeds.
*
* \param ctx HMAC_DRBG context to be seeded
* \param md_info MD algorithm to use for HMAC_DRBG
* \param f_entropy Entropy callback (p_entropy, buffer to fill, buffer
* length)
* \param p_entropy Entropy context
* \param custom Personalization data (Device specific identifiers)
* (Can be NULL)
* \param len Length of personalization data
*
* \note The "security strength" as defined by NIST is set to:
* 128 bits if md_alg is SHA-1,
* 192 bits if md_alg is SHA-224,
* 256 bits if md_alg is SHA-256 or higher.
* Note that SHA-256 is just as efficient as SHA-224.
*
* \return 0 if successful, or
* MBEDTLS_ERR_MD_BAD_INPUT_DATA, or
* MBEDTLS_ERR_MD_ALLOC_FAILED, or
* MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED.
*/
int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
const mbedtls_md_info_t * md_info,
int (*f_entropy)(void *, unsigned char *, size_t),
void *p_entropy,
const unsigned char *custom,
size_t len );
/**
* \brief Initilisation of simpified HMAC_DRBG (never reseeds).
* (For use with deterministic ECDSA.)
*
* \param ctx HMAC_DRBG context to be initialised
* \param md_info MD algorithm to use for HMAC_DRBG
* \param data Concatenation of entropy string and additional data
* \param data_len Length of data in bytes
*
* \return 0 if successful, or
* MBEDTLS_ERR_MD_BAD_INPUT_DATA, or
* MBEDTLS_ERR_MD_ALLOC_FAILED.
*/
int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
const mbedtls_md_info_t * md_info,
const unsigned char *data, size_t data_len );
/**
* \brief Enable / disable prediction resistance (Default: Off)
*
* Note: If enabled, entropy is used for ctx->entropy_len before each call!
* Only use this if you have ample supply of good entropy!
*
* \param ctx HMAC_DRBG context
* \param resistance MBEDTLS_HMAC_DRBG_PR_ON or MBEDTLS_HMAC_DRBG_PR_OFF
*/
void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
int resistance );
/**
* \brief Set the amount of entropy grabbed on each reseed
* (Default: given by the security strength, which
* depends on the hash used, see \c mbedtls_hmac_drbg_init() )
*
* \param ctx HMAC_DRBG context
* \param len Amount of entropy to grab, in bytes
*/
void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx,
size_t len );
/**
* \brief Set the reseed interval
* (Default: MBEDTLS_HMAC_DRBG_RESEED_INTERVAL)
*
* \param ctx HMAC_DRBG context
* \param interval Reseed interval
*/
void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx,
int interval );
/**
* \brief HMAC_DRBG update state
*
* \param ctx HMAC_DRBG context
* \param additional Additional data to update state with, or NULL
* \param add_len Length of additional data, or 0
*
* \note Additional data is optional, pass NULL and 0 as second
* third argument if no additional data is being used.
*/
void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
const unsigned char *additional, size_t add_len );
/**
* \brief HMAC_DRBG reseeding (extracts data from entropy source)
*
* \param ctx HMAC_DRBG context
* \param additional Additional data to add to state (Can be NULL)
* \param len Length of additional data
*
* \return 0 if successful, or
* MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
*/
int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
const unsigned char *additional, size_t len );
/**
* \brief HMAC_DRBG generate random with additional update input
*
* Note: Automatically reseeds if reseed_counter is reached or PR is enabled.
*
* \param p_rng HMAC_DRBG context
* \param output Buffer to fill
* \param output_len Length of the buffer
* \param additional Additional data to update with (can be NULL)
* \param add_len Length of additional data (can be 0)
*
* \return 0 if successful, or
* MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED, or
* MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG, or
* MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG.
*/
int mbedtls_hmac_drbg_random_with_add( void *p_rng,
unsigned char *output, size_t output_len,
const unsigned char *additional,
size_t add_len );
/**
* \brief HMAC_DRBG generate random
*
* Note: Automatically reseeds if reseed_counter is reached or PR is enabled.
*
* \param p_rng HMAC_DRBG context
* \param output Buffer to fill
* \param out_len Length of the buffer
*
* \return 0 if successful, or
* MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED, or
* MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG
*/
int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len );
/**
* \brief Free an HMAC_DRBG context
*
* \param ctx HMAC_DRBG context to free.
*/
void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx );
#if defined(MBEDTLS_FS_IO)
/**
* \brief Write a seed file
*
* \param ctx HMAC_DRBG context
* \param path Name of the file
*
* \return 0 if successful, 1 on file error, or
* MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
*/
int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path );
/**
* \brief Read and update a seed file. Seed is added to this
* instance
*
* \param ctx HMAC_DRBG context
* \param path Name of the file
*
* \return 0 if successful, 1 on file error,
* MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED or
* MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG
*/
int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path );
#endif /* MBEDTLS_FS_IO */
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mbedtls_hmac_drbg_self_test( int verbose );
#endif
#ifdef __cplusplus
}
#endif
#endif /* hmac_drbg.h */

View file

@ -0,0 +1,354 @@
/**
* \file md.h
*
* \brief Generic message digest wrapper
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_MD_H
#define MBEDTLS_MD_H
#include <stddef.h>
#define MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE -0x5080 /**< The selected feature is not available. */
#define MBEDTLS_ERR_MD_BAD_INPUT_DATA -0x5100 /**< Bad input parameters to function. */
#define MBEDTLS_ERR_MD_ALLOC_FAILED -0x5180 /**< Failed to allocate memory. */
#define MBEDTLS_ERR_MD_FILE_IO_ERROR -0x5200 /**< Opening or reading of file failed. */
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
MBEDTLS_MD_NONE=0,
MBEDTLS_MD_MD2,
MBEDTLS_MD_MD4,
MBEDTLS_MD_MD5,
MBEDTLS_MD_SHA1,
MBEDTLS_MD_SHA224,
MBEDTLS_MD_SHA256,
MBEDTLS_MD_SHA384,
MBEDTLS_MD_SHA512,
MBEDTLS_MD_RIPEMD160,
} mbedtls_md_type_t;
#if defined(MBEDTLS_SHA512_C)
#define MBEDTLS_MD_MAX_SIZE 64 /* longest known is SHA512 */
#else
#define MBEDTLS_MD_MAX_SIZE 32 /* longest known is SHA256 or less */
#endif
/**
* Opaque struct defined in md_internal.h
*/
typedef struct mbedtls_md_info_t mbedtls_md_info_t;
/**
* Generic message digest context.
*/
typedef struct {
/** Information about the associated message digest */
const mbedtls_md_info_t *md_info;
/** Digest-specific context */
void *md_ctx;
/** HMAC part of the context */
void *hmac_ctx;
} mbedtls_md_context_t;
/**
* \brief Returns the list of digests supported by the generic digest module.
*
* \return a statically allocated array of digests, the last entry
* is 0.
*/
const int *mbedtls_md_list( void );
/**
* \brief Returns the message digest information associated with the
* given digest name.
*
* \param md_name Name of the digest to search for.
*
* \return The message digest information associated with md_name or
* NULL if not found.
*/
const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name );
/**
* \brief Returns the message digest information associated with the
* given digest type.
*
* \param md_type type of digest to search for.
*
* \return The message digest information associated with md_type or
* NULL if not found.
*/
const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type );
/**
* \brief Initialize a md_context (as NONE)
* This should always be called first.
* Prepares the context for mbedtls_md_setup() or mbedtls_md_free().
*/
void mbedtls_md_init( mbedtls_md_context_t *ctx );
/**
* \brief Free and clear the internal structures of ctx.
* Can be called at any time after mbedtls_md_init().
* Mandatory once mbedtls_md_setup() has been called.
*/
void mbedtls_md_free( mbedtls_md_context_t *ctx );
#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif
/**
* \brief Select MD to use and allocate internal structures.
* Should be called after mbedtls_md_init() or mbedtls_md_free().
* Makes it necessary to call mbedtls_md_free() later.
*
* \deprecated Superseded by mbedtls_md_setup() in 2.0.0
*
* \param ctx Context to set up.
* \param md_info Message digest to use.
*
* \returns \c 0 on success,
* \c MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter failure,
* \c MBEDTLS_ERR_MD_ALLOC_FAILED memory allocation failure.
*/
int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info ) MBEDTLS_DEPRECATED;
#undef MBEDTLS_DEPRECATED
#endif /* MBEDTLS_DEPRECATED_REMOVED */
/**
* \brief Select MD to use and allocate internal structures.
* Should be called after mbedtls_md_init() or mbedtls_md_free().
* Makes it necessary to call mbedtls_md_free() later.
*
* \param ctx Context to set up.
* \param md_info Message digest to use.
* \param hmac 0 to save some memory if HMAC will not be used,
* non-zero is HMAC is going to be used with this context.
*
* \returns \c 0 on success,
* \c MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter failure,
* \c MBEDTLS_ERR_MD_ALLOC_FAILED memory allocation failure.
*/
int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac );
/**
* \brief Clone the state of an MD context
*
* \note The two contexts must have been setup to the same type
* (cloning from SHA-256 to SHA-512 make no sense).
*
* \warning Only clones the MD state, not the HMAC state! (for now)
*
* \param dst The destination context
* \param src The context to be cloned
*
* \return \c 0 on success,
* \c MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter failure.
*/
int mbedtls_md_clone( mbedtls_md_context_t *dst,
const mbedtls_md_context_t *src );
/**
* \brief Returns the size of the message digest output.
*
* \param md_info message digest info
*
* \return size of the message digest output in bytes.
*/
unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info );
/**
* \brief Returns the type of the message digest output.
*
* \param md_info message digest info
*
* \return type of the message digest output.
*/
mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info );
/**
* \brief Returns the name of the message digest output.
*
* \param md_info message digest info
*
* \return name of the message digest output.
*/
const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info );
/**
* \brief Prepare the context to digest a new message.
* Generally called after mbedtls_md_setup() or mbedtls_md_finish().
* Followed by mbedtls_md_update().
*
* \param ctx generic message digest context.
*
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int mbedtls_md_starts( mbedtls_md_context_t *ctx );
/**
* \brief Generic message digest process buffer
* Called between mbedtls_md_starts() and mbedtls_md_finish().
* May be called repeatedly.
*
* \param ctx Generic message digest context
* \param input buffer holding the datal
* \param ilen length of the input data
*
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen );
/**
* \brief Generic message digest final digest
* Called after mbedtls_md_update().
* Usually followed by mbedtls_md_free() or mbedtls_md_starts().
*
* \param ctx Generic message digest context
* \param output Generic message digest checksum result
*
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output );
/**
* \brief Output = message_digest( input buffer )
*
* \param md_info message digest info
* \param input buffer holding the data
* \param ilen length of the input data
* \param output Generic message digest checksum result
*
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
unsigned char *output );
#if defined(MBEDTLS_FS_IO)
/**
* \brief Output = message_digest( file contents )
*
* \param md_info message digest info
* \param path input file name
* \param output generic message digest checksum result
*
* \return 0 if successful,
* MBEDTLS_ERR_MD_FILE_IO_ERROR if file input failed,
* MBEDTLS_ERR_MD_BAD_INPUT_DATA if md_info was NULL.
*/
int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path,
unsigned char *output );
#endif /* MBEDTLS_FS_IO */
/**
* \brief Set HMAC key and prepare to authenticate a new message.
* Usually called after mbedtls_md_setup() or mbedtls_md_hmac_finish().
*
* \param ctx HMAC context
* \param key HMAC secret key
* \param keylen length of the HMAC key in bytes
*
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key,
size_t keylen );
/**
* \brief Generic HMAC process buffer.
* Called between mbedtls_md_hmac_starts() or mbedtls_md_hmac_reset()
* and mbedtls_md_hmac_finish().
* May be called repeatedly.
*
* \param ctx HMAC context
* \param input buffer holding the data
* \param ilen length of the input data
*
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input,
size_t ilen );
/**
* \brief Output HMAC.
* Called after mbedtls_md_hmac_update().
* Usually followed by mbedtls_md_hmac_reset(),
* mbedtls_md_hmac_starts(), or mbedtls_md_free().
*
* \param ctx HMAC context
* \param output Generic HMAC checksum result
*
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output);
/**
* \brief Prepare to authenticate a new message with the same key.
* Called after mbedtls_md_hmac_finish() and before
* mbedtls_md_hmac_update().
*
* \param ctx HMAC context to be reset
*
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx );
/**
* \brief Output = Generic_HMAC( hmac key, input buffer )
*
* \param md_info message digest info
* \param key HMAC secret key
* \param keylen length of the HMAC key in bytes
* \param input buffer holding the data
* \param ilen length of the input data
* \param output Generic HMAC-result
*
* \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char *output );
/* Internal use */
int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data );
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_MD_H */

View file

@ -0,0 +1,136 @@
/**
* \file md2.h
*
* \brief MD2 message digest algorithm (hash function)
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_MD2_H
#define MBEDTLS_MD2_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#if !defined(MBEDTLS_MD2_ALT)
// Regular implementation
//
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief MD2 context structure
*/
typedef struct
{
unsigned char cksum[16]; /*!< checksum of the data block */
unsigned char state[48]; /*!< intermediate digest state */
unsigned char buffer[16]; /*!< data block being processed */
size_t left; /*!< amount of data in buffer */
}
mbedtls_md2_context;
/**
* \brief Initialize MD2 context
*
* \param ctx MD2 context to be initialized
*/
void mbedtls_md2_init( mbedtls_md2_context *ctx );
/**
* \brief Clear MD2 context
*
* \param ctx MD2 context to be cleared
*/
void mbedtls_md2_free( mbedtls_md2_context *ctx );
/**
* \brief Clone (the state of) an MD2 context
*
* \param dst The destination context
* \param src The context to be cloned
*/
void mbedtls_md2_clone( mbedtls_md2_context *dst,
const mbedtls_md2_context *src );
/**
* \brief MD2 context setup
*
* \param ctx context to be initialized
*/
void mbedtls_md2_starts( mbedtls_md2_context *ctx );
/**
* \brief MD2 process buffer
*
* \param ctx MD2 context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void mbedtls_md2_update( mbedtls_md2_context *ctx, const unsigned char *input, size_t ilen );
/**
* \brief MD2 final digest
*
* \param ctx MD2 context
* \param output MD2 checksum result
*/
void mbedtls_md2_finish( mbedtls_md2_context *ctx, unsigned char output[16] );
#ifdef __cplusplus
}
#endif
#else /* MBEDTLS_MD2_ALT */
#include "md2_alt.h"
#endif /* MBEDTLS_MD2_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Output = MD2( input buffer )
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output MD2 checksum result
*/
void mbedtls_md2( const unsigned char *input, size_t ilen, unsigned char output[16] );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mbedtls_md2_self_test( int verbose );
/* Internal use */
void mbedtls_md2_process( mbedtls_md2_context *ctx );
#ifdef __cplusplus
}
#endif
#endif /* mbedtls_md2.h */

View file

@ -0,0 +1,136 @@
/**
* \file md4.h
*
* \brief MD4 message digest algorithm (hash function)
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_MD4_H
#define MBEDTLS_MD4_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include <stdint.h>
#if !defined(MBEDTLS_MD4_ALT)
// Regular implementation
//
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief MD4 context structure
*/
typedef struct
{
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[4]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
}
mbedtls_md4_context;
/**
* \brief Initialize MD4 context
*
* \param ctx MD4 context to be initialized
*/
void mbedtls_md4_init( mbedtls_md4_context *ctx );
/**
* \brief Clear MD4 context
*
* \param ctx MD4 context to be cleared
*/
void mbedtls_md4_free( mbedtls_md4_context *ctx );
/**
* \brief Clone (the state of) an MD4 context
*
* \param dst The destination context
* \param src The context to be cloned
*/
void mbedtls_md4_clone( mbedtls_md4_context *dst,
const mbedtls_md4_context *src );
/**
* \brief MD4 context setup
*
* \param ctx context to be initialized
*/
void mbedtls_md4_starts( mbedtls_md4_context *ctx );
/**
* \brief MD4 process buffer
*
* \param ctx MD4 context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void mbedtls_md4_update( mbedtls_md4_context *ctx, const unsigned char *input, size_t ilen );
/**
* \brief MD4 final digest
*
* \param ctx MD4 context
* \param output MD4 checksum result
*/
void mbedtls_md4_finish( mbedtls_md4_context *ctx, unsigned char output[16] );
#ifdef __cplusplus
}
#endif
#else /* MBEDTLS_MD4_ALT */
#include "md4_alt.h"
#endif /* MBEDTLS_MD4_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Output = MD4( input buffer )
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output MD4 checksum result
*/
void mbedtls_md4( const unsigned char *input, size_t ilen, unsigned char output[16] );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mbedtls_md4_self_test( int verbose );
/* Internal use */
void mbedtls_md4_process( mbedtls_md4_context *ctx, const unsigned char data[64] );
#ifdef __cplusplus
}
#endif
#endif /* mbedtls_md4.h */

View file

@ -0,0 +1,136 @@
/**
* \file md5.h
*
* \brief MD5 message digest algorithm (hash function)
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_MD5_H
#define MBEDTLS_MD5_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include <stdint.h>
#if !defined(MBEDTLS_MD5_ALT)
// Regular implementation
//
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief MD5 context structure
*/
typedef struct
{
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[4]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
}
mbedtls_md5_context;
/**
* \brief Initialize MD5 context
*
* \param ctx MD5 context to be initialized
*/
void mbedtls_md5_init( mbedtls_md5_context *ctx );
/**
* \brief Clear MD5 context
*
* \param ctx MD5 context to be cleared
*/
void mbedtls_md5_free( mbedtls_md5_context *ctx );
/**
* \brief Clone (the state of) an MD5 context
*
* \param dst The destination context
* \param src The context to be cloned
*/
void mbedtls_md5_clone( mbedtls_md5_context *dst,
const mbedtls_md5_context *src );
/**
* \brief MD5 context setup
*
* \param ctx context to be initialized
*/
void mbedtls_md5_starts( mbedtls_md5_context *ctx );
/**
* \brief MD5 process buffer
*
* \param ctx MD5 context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void mbedtls_md5_update( mbedtls_md5_context *ctx, const unsigned char *input, size_t ilen );
/**
* \brief MD5 final digest
*
* \param ctx MD5 context
* \param output MD5 checksum result
*/
void mbedtls_md5_finish( mbedtls_md5_context *ctx, unsigned char output[16] );
/* Internal use */
void mbedtls_md5_process( mbedtls_md5_context *ctx, const unsigned char data[64] );
#ifdef __cplusplus
}
#endif
#else /* MBEDTLS_MD5_ALT */
#include "md5_alt.h"
#endif /* MBEDTLS_MD5_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Output = MD5( input buffer )
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output MD5 checksum result
*/
void mbedtls_md5( const unsigned char *input, size_t ilen, unsigned char output[16] );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mbedtls_md5_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* mbedtls_md5.h */

View file

@ -0,0 +1,114 @@
/**
* \file md_internal.h
*
* \brief Message digest wrappers.
*
* \warning This in an internal header. Do not include directly.
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_MD_WRAP_H
#define MBEDTLS_MD_WRAP_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "md.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Message digest information.
* Allows message digest functions to be called in a generic way.
*/
struct mbedtls_md_info_t
{
/** Digest identifier */
mbedtls_md_type_t type;
/** Name of the message digest */
const char * name;
/** Output length of the digest function in bytes */
int size;
/** Block length of the digest function in bytes */
int block_size;
/** Digest initialisation function */
void (*starts_func)( void *ctx );
/** Digest update function */
void (*update_func)( void *ctx, const unsigned char *input, size_t ilen );
/** Digest finalisation function */
void (*finish_func)( void *ctx, unsigned char *output );
/** Generic digest function */
void (*digest_func)( const unsigned char *input, size_t ilen,
unsigned char *output );
/** Allocate a new context */
void * (*ctx_alloc_func)( void );
/** Free the given context */
void (*ctx_free_func)( void *ctx );
/** Clone state from a context */
void (*clone_func)( void *dst, const void *src );
/** Internal use only */
void (*process_func)( void *ctx, const unsigned char *input );
};
#if defined(MBEDTLS_MD2_C)
extern const mbedtls_md_info_t mbedtls_md2_info;
#endif
#if defined(MBEDTLS_MD4_C)
extern const mbedtls_md_info_t mbedtls_md4_info;
#endif
#if defined(MBEDTLS_MD5_C)
extern const mbedtls_md_info_t mbedtls_md5_info;
#endif
#if defined(MBEDTLS_RIPEMD160_C)
extern const mbedtls_md_info_t mbedtls_ripemd160_info;
#endif
#if defined(MBEDTLS_SHA1_C)
extern const mbedtls_md_info_t mbedtls_sha1_info;
#endif
#if defined(MBEDTLS_SHA256_C)
extern const mbedtls_md_info_t mbedtls_sha224_info;
extern const mbedtls_md_info_t mbedtls_sha256_info;
#endif
#if defined(MBEDTLS_SHA512_C)
extern const mbedtls_md_info_t mbedtls_sha384_info;
extern const mbedtls_md_info_t mbedtls_sha512_info;
#endif
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_MD_WRAP_H */

View file

@ -0,0 +1,150 @@
/**
* \file memory_buffer_alloc.h
*
* \brief Buffer-based memory allocator
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_MEMORY_BUFFER_ALLOC_H
#define MBEDTLS_MEMORY_BUFFER_ALLOC_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
/**
* \name SECTION: Module settings
*
* The configuration options you can set for this module are in this section.
* Either change them in config.h or define them on the compiler command line.
* \{
*/
#if !defined(MBEDTLS_MEMORY_ALIGN_MULTIPLE)
#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */
#endif
/* \} name SECTION: Module settings */
#define MBEDTLS_MEMORY_VERIFY_NONE 0
#define MBEDTLS_MEMORY_VERIFY_ALLOC (1 << 0)
#define MBEDTLS_MEMORY_VERIFY_FREE (1 << 1)
#define MBEDTLS_MEMORY_VERIFY_ALWAYS (MBEDTLS_MEMORY_VERIFY_ALLOC | MBEDTLS_MEMORY_VERIFY_FREE)
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Initialize use of stack-based memory allocator.
* The stack-based allocator does memory management inside the
* presented buffer and does not call calloc() and free().
* It sets the global mbedtls_calloc() and mbedtls_free() pointers
* to its own functions.
* (Provided mbedtls_calloc() and mbedtls_free() are thread-safe if
* MBEDTLS_THREADING_C is defined)
*
* \note This code is not optimized and provides a straight-forward
* implementation of a stack-based memory allocator.
*
* \param buf buffer to use as heap
* \param len size of the buffer
*/
void mbedtls_memory_buffer_alloc_init( unsigned char *buf, size_t len );
/**
* \brief Free the mutex for thread-safety and clear remaining memory
*/
void mbedtls_memory_buffer_alloc_free( void );
/**
* \brief Determine when the allocator should automatically verify the state
* of the entire chain of headers / meta-data.
* (Default: MBEDTLS_MEMORY_VERIFY_NONE)
*
* \param verify One of MBEDTLS_MEMORY_VERIFY_NONE, MBEDTLS_MEMORY_VERIFY_ALLOC,
* MBEDTLS_MEMORY_VERIFY_FREE or MBEDTLS_MEMORY_VERIFY_ALWAYS
*/
void mbedtls_memory_buffer_set_verify( int verify );
#if defined(MBEDTLS_MEMORY_DEBUG)
/**
* \brief Print out the status of the allocated memory (primarily for use
* after a program should have de-allocated all memory)
* Prints out a list of 'still allocated' blocks and their stack
* trace if MBEDTLS_MEMORY_BACKTRACE is defined.
*/
void mbedtls_memory_buffer_alloc_status( void );
/**
* \brief Get the peak heap usage so far
*
* \param max_used Peak number of bytes in use or committed. This
* includes bytes in allocated blocks too small to split
* into smaller blocks but larger than the requested size.
* \param max_blocks Peak number of blocks in use, including free and used
*/
void mbedtls_memory_buffer_alloc_max_get( size_t *max_used, size_t *max_blocks );
/**
* \brief Reset peak statistics
*/
void mbedtls_memory_buffer_alloc_max_reset( void );
/**
* \brief Get the current heap usage
*
* \param cur_used Current number of bytes in use or committed. This
* includes bytes in allocated blocks too small to split
* into smaller blocks but larger than the requested size.
* \param cur_blocks Current number of blocks in use, including free and used
*/
void mbedtls_memory_buffer_alloc_cur_get( size_t *cur_used, size_t *cur_blocks );
#endif /* MBEDTLS_MEMORY_DEBUG */
/**
* \brief Verifies that all headers in the memory buffer are correct
* and contain sane values. Helps debug buffer-overflow errors.
*
* Prints out first failure if MBEDTLS_MEMORY_DEBUG is defined.
* Prints out full header information if MBEDTLS_MEMORY_DEBUG
* is defined. (Includes stack trace information for each block if
* MBEDTLS_MEMORY_BACKTRACE is defined as well).
*
* \return 0 if verified, 1 otherwise
*/
int mbedtls_memory_buffer_alloc_verify( void );
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if a test failed
*/
int mbedtls_memory_buffer_alloc_self_test( int verbose );
#endif
#ifdef __cplusplus
}
#endif
#endif /* memory_buffer_alloc.h */

View file

@ -0,0 +1,31 @@
/**
* \file net.h
*
* \brief Deprecated header file that includes mbedtls/net_sockets.h
*
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*
* \deprecated Superseded by mbedtls/net_sockets.h
*/
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
#include "mbedtls/net_sockets.h"
#if defined(MBEDTLS_DEPRECATED_WARNING)
#warning "Deprecated header file: Superseded by mbedtls/net_sockets.h"
#endif /* MBEDTLS_DEPRECATED_WARNING */
#endif /* !MBEDTLS_DEPRECATED_REMOVED */

Some files were not shown because too many files have changed in this diff Show more