| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399 |
- /*
- * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
- *
- * SPDX-License-Identifier: CC0-1.0
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "soc/soc_caps.h"
- #if SOC_SHA_SUPPORTED
- #include "soc/periph_defs.h"
- #include "esp_private/periph_ctrl.h"
- #include "hal/sha_hal.h"
- #include "hal/clk_gate_ll.h"
- #include "sha_block.h"
- #if defined(SOC_SHA_SUPPORT_SHA1)
- static void sha1_update_block(sha1_ctx* ctx, esp_sha_type sha_type, const unsigned char *input, size_t ilen)
- {
- size_t fill;
- uint32_t left, local_len = 0;
- left = ctx->total[0] & 0x3F;
- fill = 64 - left;
- ctx->total[0] += (uint32_t) ilen;
- ctx->total[0] &= 0xFFFFFFFF;
- if ( ctx->total[0] < (uint32_t) ilen ) {
- ctx->total[1]++;
- }
- if ( left && ilen >= fill ) {
- memcpy( (void *) (ctx->buffer + left), input, fill );
- input += fill;
- ilen -= fill;
- left = 0;
- local_len = 64;
- }
- if ( (ilen >= 64) || local_len) {
- /* Enable peripheral module */
- periph_ll_enable_clk_clear_rst(PERIPH_SHA_MODULE);
- if (ctx->first_block == 0) {
- /* Writes the message digest to the SHA engine */
- sha_hal_write_digest(sha_type, ctx->state);
- }
- /* First process buffered block, if any */
- if ( local_len ) {
- /* Hash a single block */
- sha_hal_hash_block(sha_type, ctx->buffer, block_length(sha_type)/4, ctx->first_block);
- if (ctx->first_block == 1) {
- ctx->first_block = 0;
- }
- }
- while ( ilen >= 64 ) {
- sha_hal_hash_block(sha_type, input, block_length(sha_type)/4, ctx->first_block);
- if (ctx->first_block == 1) {
- ctx->first_block = 0;
- }
- input += 64;
- ilen -= 64;
- }
- /* Reads the current message digest from the SHA engine */
- sha_hal_read_digest(sha_type, ctx->state);
- /* Disable peripheral module */
- periph_ll_disable_clk_set_rst(PERIPH_SHA_MODULE);
- }
- if ( ilen > 0 ) {
- memcpy( (void *) (ctx->buffer + left), input, ilen);
- }
- }
- void sha1_block(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output)
- {
- sha1_ctx ctx;
- memset(&ctx, 0, sizeof(sha1_ctx));
- ctx.first_block = 1;
- sha1_update_block(&ctx, sha_type, input, ilen);
- uint32_t last, padn;
- uint32_t high, low;
- unsigned char msglen[8];
- high = ( ctx.total[0] >> 29 )
- | ( ctx.total[1] << 3 );
- low = ( ctx.total[0] << 3 );
- PUT_UINT32_BE( high, msglen, 0 );
- PUT_UINT32_BE( low, msglen, 4 );
- last = ctx.total[0] & 0x3F;
- padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
- sha1_update_block(&ctx, sha_type, sha1_padding, padn);
- sha1_update_block(&ctx, sha_type, msglen, 8);
- memcpy(output, ctx.state, 20);
- }
- #endif /* defined(SOC_SHA_SUPPORT_SHA1) */
- #if defined(SOC_SHA_SUPPORT_SHA224) || defined(SOC_SHA_SUPPORT_SHA256)
- static void sha256_update_block(sha256_ctx* ctx, esp_sha_type sha_type, const unsigned char *input, size_t ilen)
- {
- size_t fill;
- uint32_t left, local_len = 0;
- left = ctx->total[0] & 0x3F;
- fill = 64 - left;
- ctx->total[0] += (uint32_t) ilen;
- ctx->total[0] &= 0xFFFFFFFF;
- if ( ctx->total[0] < (uint32_t) ilen ) {
- ctx->total[1]++;
- }
- if ( left && ilen >= fill ) {
- memcpy( (void *) (ctx->buffer + left), input, fill );
- input += fill;
- ilen -= fill;
- left = 0;
- local_len = 64;
- }
- if ( (ilen >= 64) || local_len) {
- /* Enable peripheral module */
- periph_ll_enable_clk_clear_rst(PERIPH_SHA_MODULE);
- if (ctx->first_block == 0) {
- /* Writes the message digest to the SHA engine */
- sha_hal_write_digest(sha_type, ctx->state);
- }
- /* First process buffered block, if any */
- if ( local_len ) {
- /* Hash a single block */
- sha_hal_hash_block(sha_type, ctx->buffer, block_length(sha_type)/4, ctx->first_block);
- if (ctx->first_block == 1) {
- ctx->first_block = 0;
- }
- }
- while ( ilen >= 64 ) {
- sha_hal_hash_block(sha_type, input, block_length(sha_type)/4, ctx->first_block);
- if (ctx->first_block == 1) {
- ctx->first_block = 0;
- }
- input += 64;
- ilen -= 64;
- }
- /* Reads the current message digest from the SHA engine */
- sha_hal_read_digest(sha_type, ctx->state);
- /* Disable peripheral module */
- periph_ll_disable_clk_set_rst(PERIPH_SHA_MODULE);
- }
- if ( ilen > 0 ) {
- memcpy( (void *) (ctx->buffer + left), input, ilen);
- }
- }
- void sha256_block(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output)
- {
- sha256_ctx ctx;
- memset(&ctx, 0, sizeof(sha256_ctx));
- ctx.first_block = 1;
- sha256_update_block(&ctx, sha_type, input, ilen);
- uint32_t last, padn;
- uint32_t high, low;
- unsigned char msglen[8];
- high = ( ctx.total[0] >> 29 )
- | ( ctx.total[1] << 3 );
- low = ( ctx.total[0] << 3 );
- PUT_UINT32_BE( high, msglen, 0 );
- PUT_UINT32_BE( low, msglen, 4 );
- last = ctx.total[0] & 0x3F;
- padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
- sha256_update_block(&ctx, sha_type, sha256_padding, padn);
- sha256_update_block(&ctx, sha_type, msglen, 8);
- if (sha_type == SHA2_256) {
- memcpy(output, ctx.state, 32);
- } else if (sha_type == SHA2_224) {
- memcpy(output, ctx.state, 28);
- }
- }
- #endif /* defined(SOC_SHA_SUPPORT_SHA224) || defined(SOC_SHA_SUPPORT_SHA256) */
- #if defined(SOC_SHA_SUPPORT_SHA384) || defined(SOC_SHA_SUPPORT_SHA512)
- #if SOC_SHA_SUPPORT_SHA512_T
- int sha_512_t_init_hash_block(uint16_t t)
- {
- uint32_t t_string = 0;
- uint8_t t0, t1, t2, t_len;
- if (t == 384) {
- return -1;
- }
- if (t <= 9) {
- t_string = (uint32_t)((1 << 23) | ((0x30 + t) << 24));
- t_len = 0x48;
- } else if (t <= 99) {
- t0 = t % 10;
- t1 = (t / 10) % 10;
- t_string = (uint32_t)((1 << 15) | ((0x30 + t0) << 16) |
- (((0x30 + t1) << 24)));
- t_len = 0x50;
- } else if (t <= 512) {
- t0 = t % 10;
- t1 = (t / 10) % 10;
- t2 = t / 100;
- t_string = (uint32_t)((1 << 7) | ((0x30 + t0) << 8) |
- (((0x30 + t1) << 16) + ((0x30 + t2) << 24)));
- t_len = 0x58;
- } else {
- return -1;
- }
- /* Calculates and sets the initial digiest for SHA512_t */
- sha_hal_sha512_init_hash(t_string, t_len);
- return 0;
- }
- #endif //SOC_SHA_SUPPORT_SHA512_T
- static void sha512_update_block(sha512_ctx* ctx, esp_sha_type sha_type, const unsigned char *input, size_t ilen)
- {
- size_t fill;
- unsigned int left, local_len = 0;
- left = (unsigned int) (ctx->total[0] & 0x7F);
- fill = 128 - left;
- ctx->total[0] += (uint64_t) ilen;
- if ( ctx->total[0] < (uint64_t) ilen ) {
- ctx->total[1]++;
- }
- if ( left && ilen >= fill ) {
- memcpy( (void *) (ctx->buffer + left), input, fill );
- input += fill;
- ilen -= fill;
- left = 0;
- local_len = 128;
- }
- if ( (ilen >= 128) || local_len) {
- /* Enable peripheral module */
- periph_ll_enable_clk_clear_rst(PERIPH_SHA_MODULE);
- if (ctx->first_block && sha_type == SHA2_512T){
- sha_512_t_init_hash_block(ctx->t_val);
- ctx->first_block = 0;
- }
- else if (ctx->first_block == 0) {
- /* Writes the message digest to the SHA engine */
- sha_hal_write_digest(sha_type, ctx->state);
- }
- /* First process buffered block, if any */
- if ( local_len ) {
- /* Hash a single block */
- sha_hal_hash_block(sha_type, ctx->buffer, block_length(sha_type)/4, ctx->first_block);
- if (ctx->first_block == 1) {
- ctx->first_block = 0;
- }
- }
- while ( ilen >= 128 ) {
- sha_hal_hash_block(sha_type, input, block_length(sha_type)/4, ctx->first_block);
- if (ctx->first_block == 1) {
- ctx->first_block = 0;
- }
- input += 128;
- ilen -= 128;
- }
- /* Reads the current message digest from the SHA engine */
- sha_hal_read_digest(sha_type, ctx->state);
- /* Disable peripheral module */
- periph_ll_disable_clk_set_rst(PERIPH_SHA_MODULE);
- }
- if ( ilen > 0 ) {
- memcpy( (void *) (ctx->buffer + left), input, ilen);
- }
- }
- void sha512_block(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output)
- {
- sha512_ctx ctx;
- memset(&ctx, 0, sizeof(sha512_ctx));
- ctx.first_block = 1;
- sha512_update_block(&ctx, sha_type, input, ilen);
- size_t last, padn;
- uint64_t high, low;
- unsigned char msglen[16];
- high = ( ctx.total[0] >> 61 )
- | ( ctx.total[1] << 3 );
- low = ( ctx.total[0] << 3 );
- PUT_UINT64_BE( high, msglen, 0 );
- PUT_UINT64_BE( low, msglen, 8 );
- last = (size_t)( ctx.total[0] & 0x7F );
- padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
- sha512_update_block( &ctx, sha_type, sha512_padding, padn );
- sha512_update_block( &ctx, sha_type, msglen, 16 );
- if (sha_type == SHA2_384) {
- memcpy(output, ctx.state, 48);
- } else {
- memcpy(output, ctx.state, 64);
- }
- }
- #endif /* defined(SOC_SHA_SUPPORT_SHA384) || defined(SOC_SHA_SUPPORT_SHA512) */
- #if SOC_SHA_SUPPORT_SHA512_T
- void sha512t_block(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output, uint32_t t_val)
- {
- sha512_ctx ctx;
- memset(&ctx, 0, sizeof(sha512_ctx));
- ctx.first_block = 1;
- ctx.t_val = t_val;
- sha512_update_block(&ctx, sha_type, input, ilen);
- size_t last, padn;
- uint64_t high, low;
- unsigned char msglen[16];
- high = ( ctx.total[0] >> 61 )
- | ( ctx.total[1] << 3 );
- low = ( ctx.total[0] << 3 );
- PUT_UINT64_BE( high, msglen, 0 );
- PUT_UINT64_BE( low, msglen, 8 );
- last = (size_t)( ctx.total[0] & 0x7F );
- padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
- sha512_update_block( &ctx, sha_type, sha512_padding, padn );
- sha512_update_block( &ctx, sha_type, msglen, 16 );
- if (sha_type == SHA2_384) {
- memcpy(output, ctx.state, 48);
- } else {
- memcpy(output, ctx.state, 64);
- }
- }
- #endif /*SOC_SHA_SUPPORT_SHA512_T*/
- #endif /*SOC_SHA_SUPPORTED*/
|