blob: 0ef01f48fe34ba1276fc6bb80b74effe4e3fab07 [file] [log] [blame]
/*
*
* Copyright (c) 2020 Project CHIP Authors
* Copyright (c) 2020 Texas Instruments Incorporated
*
* 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.
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <mbedtls/sha256.h>
#if defined(MBEDTLS_SHA256_ALT)
#include <string.h>
#include <ti/drivers/SHA2.h>
#include <ti/drivers/sha2/SHA2CC26X2.h>
/*!
* Hardware-specific configuration attributes, may be replaced with SysConfig
* ti_drivers.h structure.
*/
const SHA2CC26X2_HWAttrs sha2CC26X2HWAttrs_sha = {
.intPriority = ~0,
};
void mbedtls_sha256_init(mbedtls_sha256_context * ctx)
{
SHA2_Params sha2Params;
memset(ctx, 0, sizeof(mbedtls_sha256_context));
SHA2_Params_init(&sha2Params);
sha2Params.returnBehavior = SHA2_RETURN_BEHAVIOR_POLLING;
ctx->config.object = &ctx->object;
ctx->config.hwAttrs = &sha2CC26X2HWAttrs_sha;
ctx->hndl = SHA2_construct(&ctx->config, &sha2Params);
}
void mbedtls_sha256_free(mbedtls_sha256_context * ctx)
{
if (NULL == ctx)
{
return;
}
if (ctx->hndl != NULL)
{
SHA2_close(ctx->hndl);
memset(ctx, 0, sizeof(mbedtls_sha256_context));
}
}
/*
* Deviation from documentation in sha256.h.
*
* It has been noticed that some code using mbedtls does not call `init` before
* starting a SHA operation. Rather these implementations assume the `ctx`
* structure may be zero'ed out as initialization. To support this usage the
* driver instance is assumed to be uninitialized if the context's `hndl` is a
* NULL pointer. Start will initialize the driver and assign the handle to the
* context in this case.
*/
int mbedtls_sha256_starts_ret(mbedtls_sha256_context * ctx, int is224)
{
SHA2_HashType type;
// open the driver here because no-one called init
if (ctx->hndl == NULL)
{
SHA2_Params sha2Params;
SHA2_Params_init(&sha2Params);
sha2Params.returnBehavior = SHA2_RETURN_BEHAVIOR_POLLING;
ctx->config.object = &ctx->object;
ctx->config.hwAttrs = &sha2CC26X2HWAttrs_sha;
ctx->hndl = SHA2_construct(&ctx->config, &sha2Params);
if (NULL == ctx->hndl)
{
return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
}
}
else
{
SHA2_reset(ctx->hndl);
}
if (is224)
{
type = SHA2_HASH_TYPE_224;
}
else
{
type = SHA2_HASH_TYPE_256;
}
SHA2_setHashType(ctx->hndl, type);
return 0;
}
/**
* Deviation from documentation in sha256.h.
*
* It has been noticed that some code using mbedtls does not call `init` on the
* contexts being passed into this function. This seems to be done to avoid
* allocating hardware to cloned context instances. To support this use-case,
* only internal buffers to the SHA2 structure are copied without checking the
* driver handles.
*/
void mbedtls_sha256_clone(mbedtls_sha256_context * dst, const mbedtls_sha256_context * src)
{
dst->object.hashType = src->object.hashType;
dst->object.bytesInBuffer = src->object.bytesInBuffer;
dst->object.bytesProcessed = src->object.bytesProcessed;
memcpy(dst->object.buffer, src->object.buffer, sizeof(dst->object.buffer));
// copy the digest to support cloning after finalization has happened
memcpy(dst->object.digest, src->object.digest, sizeof(dst->object.digest));
}
int mbedtls_sha256_finish_ret(mbedtls_sha256_context * ctx, unsigned char output[32])
{
int_fast16_t result;
result = SHA2_finalize(ctx->hndl, output);
if (SHA2_STATUS_SUCCESS != result)
{
return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
}
else
{
return 0;
}
}
int mbedtls_sha256_update_ret(mbedtls_sha256_context * ctx, const unsigned char * input, size_t ilen)
{
int_fast16_t result;
// Process data in chunks. The driver buffers incomplete blocks internally.
result = SHA2_addData(ctx->hndl, input, ilen);
if (SHA2_STATUS_SUCCESS != result)
{
return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
}
else
{
return 0;
}
}
int mbedtls_internal_sha256_process(mbedtls_sha256_context * ctx, const unsigned char data[64])
{
int_fast16_t result;
// Process data in chunks. The driver buffers incomplete blocks internally.
result = SHA2_addData(ctx->hndl, data, SHA2_BLOCK_SIZE_BYTES_256);
if (SHA2_STATUS_SUCCESS != result)
{
return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
}
else
{
return 0;
}
}
#endif /* MBEDTLS_SHA256_ALT */