/* * ESP32 hardware accelerated SHA1/256/512 implementation * based on mbedTLS FIPS-197 compliant version. * * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE Ltd * 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. * *//* ... *//* * The SHA-1 standard was published by NIST in 1993. * * http://www.itl.nist.gov/fipspubs/fip180-1.htm *//* ... */#include<string.h>#include<stdio.h>#include<machine/endian.h>#include<assert.h>#include"freertos/FreeRTOS.h"#include"freertos/semphr.h"#include"esp_cpu.h"#include"hal/sha_hal.h"#include"hal/sha_ll.h"#include"hal/sha_types.h"#include"sha/sha_parallel_engine.h"#include"soc/hwcrypto_periph.h"#include"esp_private/esp_crypto_lock_internal.h"#include"esp_private/periph_ctrl.h"14 includes/* Single spinlock for SHA engine memory block*//* ... */staticportMUX_TYPEmemory_block_lock=portMUX_INITIALIZER_UNLOCKED;/* Binary semaphore managing the state of each concurrent SHA engine. Available = noone is using this SHA engine Taken = a SHA session is running on this SHA engine Indexes: 0 = SHA1 1 = SHA2_256 2 = SHA2_384 or SHA2_512*//* ... */staticSemaphoreHandle_tengine_states[3];staticuint8_tengines_in_use;/* Spinlock for engines_in_use counter*//* ... */staticportMUX_TYPEengines_in_use_lock=portMUX_INITIALIZER_UNLOCKED;/* Return block size (in words) for a given SHA type */inlinestaticsize_tblock_length(esp_sha_typetype){switch(type){caseSHA1:caseSHA2_256:return64/4;...caseSHA2_384:caseSHA2_512:return128/4;...default:return0;...}{...}}{ ... }/* Index into the engine_states array */inlinestaticsize_tsha_engine_index(esp_sha_typetype){switch(type){caseSHA1:return0;...caseSHA2_256:return1;...default:return2;...}{...}}{ ... }voidesp_sha_lock_memory_block(void){portENTER_CRITICAL(&memory_block_lock);}{ ... }voidesp_sha_unlock_memory_block(void){portEXIT_CRITICAL(&memory_block_lock);}{ ... }staticSemaphoreHandle_tsha_get_engine_state(esp_sha_typesha_type){unsignedidx=sha_engine_index(sha_type);volatileSemaphoreHandle_t*engine=&engine_states[idx];SemaphoreHandle_tresult=*engine;if(result==NULL){// Create a new semaphore for 'in use' flagSemaphoreHandle_tnew_engine=xSemaphoreCreateBinary();assert(new_engine!=NULL);xSemaphoreGive(new_engine);// start available// try to atomically set the previously NULL *engine to new_engineif(!esp_cpu_compare_and_set((volatileuint32_t*)engine,0,(uint32_t)new_engine)){// we lost a race setting *enginevSemaphoreDelete(new_engine);}{...}result=*engine;}{...}returnresult;}{ ... }staticboolesp_sha_lock_engine_common(esp_sha_typesha_type,TickType_tticks_to_wait);boolesp_sha_try_lock_engine(esp_sha_typesha_type){returnesp_sha_lock_engine_common(sha_type,0);}{ ... }voidesp_sha_lock_engine(esp_sha_typesha_type){esp_sha_lock_engine_common(sha_type,portMAX_DELAY);}{ ... }staticboolesp_sha_lock_engine_common(esp_sha_typesha_type,TickType_tticks_to_wait){SemaphoreHandle_tengine_state=sha_get_engine_state(sha_type);BaseType_tresult=xSemaphoreTake(engine_state,ticks_to_wait);if(result==pdFALSE){// failed to take semaphorereturnfalse;}{...}portENTER_CRITICAL(&engines_in_use_lock);if(engines_in_use==0){/* Just locked first engine, so enable SHA hardware *//* ... */SHA_RCC_ATOMIC(){sha_ll_enable_bus_clock(true);sha_ll_reset_register();}{...}}{...}engines_in_use++;assert(engines_in_use<=3);portEXIT_CRITICAL(&engines_in_use_lock);returntrue;}{ ... }voidesp_sha_unlock_engine(esp_sha_typesha_type){SemaphoreHandle_tengine_state=sha_get_engine_state(sha_type);portENTER_CRITICAL(&engines_in_use_lock);engines_in_use--;if(engines_in_use==0){/* About to release last engine, so disable SHA hardware *//* ... */SHA_RCC_ATOMIC(){sha_ll_enable_bus_clock(false);}{...}}{...}portEXIT_CRITICAL(&engines_in_use_lock);xSemaphoreGive(engine_state);}{ ... }voidesp_sha_read_digest_state(esp_sha_typesha_type,void*digest_state){#ifndefNDEBUG{SemaphoreHandle_tengine_state=sha_get_engine_state(sha_type);assert(uxSemaphoreGetCount(engine_state)==0&&"SHA engine should be locked");}#endif// preemptively do this before entering the critical section, then re-check once in itsha_hal_wait_idle();esp_sha_lock_memory_block();sha_hal_read_digest(sha_type,digest_state);esp_sha_unlock_memory_block();}voidesp_sha_block(esp_sha_typesha_type,constvoid*data_block,boolfirst_block){#ifndefNDEBUG{SemaphoreHandle_tengine_state=sha_get_engine_state(sha_type);assert(uxSemaphoreGetCount(engine_state)==0&&"SHA engine should be locked");}#endif// preemptively do this before entering the critical section, then re-check once in itsha_hal_wait_idle();esp_sha_lock_memory_block();sha_hal_hash_block(sha_type,data_block,block_length(sha_type),first_block);esp_sha_unlock_memory_block();}
Details
Show: from
Types: Columns:
All items filtered out
All items filtered out
This file uses the notable symbols shown below. Click anywhere in the file to view more details.