Dependents:   cobaLCDJoyMotor_Thread odometry_omni_3roda_v3 odometry_omni_3roda_v1 odometry_omni_3roda_v2 ... more

Committer:
be_bryan
Date:
Mon Dec 11 17:54:04 2017 +0000
Revision:
0:b74591d5ab33
motor ++

Who changed what in which revision?

UserRevisionLine numberNew contents of line
be_bryan 0:b74591d5ab33 1 /*
be_bryan 0:b74591d5ab33 2 * sha256_alt.c for SHA256 HASH
be_bryan 0:b74591d5ab33 3 *******************************************************************************
be_bryan 0:b74591d5ab33 4 * Copyright (c) 2017, STMicroelectronics
be_bryan 0:b74591d5ab33 5 * SPDX-License-Identifier: Apache-2.0
be_bryan 0:b74591d5ab33 6 *
be_bryan 0:b74591d5ab33 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
be_bryan 0:b74591d5ab33 8 * not use this file except in compliance with the License.
be_bryan 0:b74591d5ab33 9 * You may obtain a copy of the License at
be_bryan 0:b74591d5ab33 10 *
be_bryan 0:b74591d5ab33 11 * http://www.apache.org/licenses/LICENSE-2.0
be_bryan 0:b74591d5ab33 12 *
be_bryan 0:b74591d5ab33 13 * Unless required by applicable law or agreed to in writing, software
be_bryan 0:b74591d5ab33 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
be_bryan 0:b74591d5ab33 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
be_bryan 0:b74591d5ab33 16 * See the License for the specific language governing permissions and
be_bryan 0:b74591d5ab33 17 * limitations under the License.
be_bryan 0:b74591d5ab33 18 *
be_bryan 0:b74591d5ab33 19 */
be_bryan 0:b74591d5ab33 20 #include "mbedtls/sha256.h"
be_bryan 0:b74591d5ab33 21
be_bryan 0:b74591d5ab33 22 #if defined(MBEDTLS_SHA256_ALT)
be_bryan 0:b74591d5ab33 23 #include "mbedtls/platform.h"
be_bryan 0:b74591d5ab33 24
be_bryan 0:b74591d5ab33 25 /* Implementation that should never be optimized out by the compiler */
be_bryan 0:b74591d5ab33 26 static void mbedtls_zeroize( void *v, size_t n ) {
be_bryan 0:b74591d5ab33 27 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
be_bryan 0:b74591d5ab33 28 }
be_bryan 0:b74591d5ab33 29
be_bryan 0:b74591d5ab33 30 static int st_sha256_restore_hw_context(mbedtls_sha256_context *ctx)
be_bryan 0:b74591d5ab33 31 {
be_bryan 0:b74591d5ab33 32 uint32_t i;
be_bryan 0:b74591d5ab33 33 uint32_t tickstart;
be_bryan 0:b74591d5ab33 34 /* allow multi-instance of HASH use: save context for HASH HW module CR */
be_bryan 0:b74591d5ab33 35 /* Check that there is no HASH activity on going */
be_bryan 0:b74591d5ab33 36 tickstart = HAL_GetTick();
be_bryan 0:b74591d5ab33 37 while ((HASH->SR & (HASH_FLAG_BUSY | HASH_FLAG_DMAS)) != 0) {
be_bryan 0:b74591d5ab33 38 if ((HAL_GetTick() - tickstart) > ST_SHA256_TIMEOUT) {
be_bryan 0:b74591d5ab33 39 return 0; // timeout: HASH processor is busy
be_bryan 0:b74591d5ab33 40 }
be_bryan 0:b74591d5ab33 41 }
be_bryan 0:b74591d5ab33 42 HASH->STR = ctx->ctx_save_str;
be_bryan 0:b74591d5ab33 43 HASH->CR = (ctx->ctx_save_cr | HASH_CR_INIT);
be_bryan 0:b74591d5ab33 44 for (i=0;i<38;i++) {
be_bryan 0:b74591d5ab33 45 HASH->CSR[i] = ctx->ctx_save_csr[i];
be_bryan 0:b74591d5ab33 46 }
be_bryan 0:b74591d5ab33 47 return 1;
be_bryan 0:b74591d5ab33 48 }
be_bryan 0:b74591d5ab33 49
be_bryan 0:b74591d5ab33 50 static int st_sha256_save_hw_context(mbedtls_sha256_context *ctx)
be_bryan 0:b74591d5ab33 51 {
be_bryan 0:b74591d5ab33 52 uint32_t i;
be_bryan 0:b74591d5ab33 53 uint32_t tickstart;
be_bryan 0:b74591d5ab33 54 /* Check that there is no HASH activity on going */
be_bryan 0:b74591d5ab33 55 tickstart = HAL_GetTick();
be_bryan 0:b74591d5ab33 56 while ((HASH->SR & (HASH_FLAG_BUSY | HASH_FLAG_DMAS)) != 0) {
be_bryan 0:b74591d5ab33 57 if ((HAL_GetTick() - tickstart) > ST_SHA256_TIMEOUT) {
be_bryan 0:b74591d5ab33 58 return 0; // timeout: HASH processor is busy
be_bryan 0:b74591d5ab33 59 }
be_bryan 0:b74591d5ab33 60 }
be_bryan 0:b74591d5ab33 61 /* allow multi-instance of HASH use: restore context for HASH HW module CR */
be_bryan 0:b74591d5ab33 62 ctx->ctx_save_cr = HASH->CR;
be_bryan 0:b74591d5ab33 63 ctx->ctx_save_str = HASH->STR;
be_bryan 0:b74591d5ab33 64 for (i=0;i<38;i++) {
be_bryan 0:b74591d5ab33 65 ctx->ctx_save_csr[i] = HASH->CSR[i];
be_bryan 0:b74591d5ab33 66 }
be_bryan 0:b74591d5ab33 67 return 1;
be_bryan 0:b74591d5ab33 68 }
be_bryan 0:b74591d5ab33 69
be_bryan 0:b74591d5ab33 70 void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
be_bryan 0:b74591d5ab33 71 {
be_bryan 0:b74591d5ab33 72 mbedtls_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
be_bryan 0:b74591d5ab33 73
be_bryan 0:b74591d5ab33 74 /* Enable HASH clock */
be_bryan 0:b74591d5ab33 75 __HAL_RCC_HASH_CLK_ENABLE();
be_bryan 0:b74591d5ab33 76 }
be_bryan 0:b74591d5ab33 77
be_bryan 0:b74591d5ab33 78 void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
be_bryan 0:b74591d5ab33 79 {
be_bryan 0:b74591d5ab33 80 if( ctx == NULL )
be_bryan 0:b74591d5ab33 81 return;
be_bryan 0:b74591d5ab33 82 mbedtls_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
be_bryan 0:b74591d5ab33 83 }
be_bryan 0:b74591d5ab33 84
be_bryan 0:b74591d5ab33 85 void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
be_bryan 0:b74591d5ab33 86 const mbedtls_sha256_context *src )
be_bryan 0:b74591d5ab33 87 {
be_bryan 0:b74591d5ab33 88 *dst = *src;
be_bryan 0:b74591d5ab33 89 }
be_bryan 0:b74591d5ab33 90
be_bryan 0:b74591d5ab33 91 void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 )
be_bryan 0:b74591d5ab33 92 {
be_bryan 0:b74591d5ab33 93 /* HASH IP initialization */
be_bryan 0:b74591d5ab33 94 if (HAL_HASH_DeInit(&ctx->hhash_sha256) == HAL_ERROR) {
be_bryan 0:b74591d5ab33 95 // error found to be returned
be_bryan 0:b74591d5ab33 96 return;
be_bryan 0:b74591d5ab33 97 }
be_bryan 0:b74591d5ab33 98
be_bryan 0:b74591d5ab33 99 ctx->is224 = is224;
be_bryan 0:b74591d5ab33 100 /* HASH Configuration */
be_bryan 0:b74591d5ab33 101 ctx->hhash_sha256.Init.DataType = HASH_DATATYPE_8B;
be_bryan 0:b74591d5ab33 102 /* clear CR ALGO value */
be_bryan 0:b74591d5ab33 103 HASH->CR &= ~HASH_CR_ALGO_Msk;
be_bryan 0:b74591d5ab33 104 if (HAL_HASH_Init(&ctx->hhash_sha256) == HAL_ERROR) {
be_bryan 0:b74591d5ab33 105 // error found to be returned
be_bryan 0:b74591d5ab33 106 return;
be_bryan 0:b74591d5ab33 107 }
be_bryan 0:b74591d5ab33 108 if (st_sha256_save_hw_context(ctx) != 1) {
be_bryan 0:b74591d5ab33 109 return; // return HASH_BUSY timeout Error here
be_bryan 0:b74591d5ab33 110 }
be_bryan 0:b74591d5ab33 111 }
be_bryan 0:b74591d5ab33 112
be_bryan 0:b74591d5ab33 113 void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[ST_SHA256_BLOCK_SIZE] )
be_bryan 0:b74591d5ab33 114 {
be_bryan 0:b74591d5ab33 115 if (st_sha256_restore_hw_context(ctx) != 1) {
be_bryan 0:b74591d5ab33 116 return; // Return HASH_BUSY timout error here
be_bryan 0:b74591d5ab33 117 }
be_bryan 0:b74591d5ab33 118 if (ctx->is224 == 0) {
be_bryan 0:b74591d5ab33 119 if (HAL_HASHEx_SHA256_Accumulate(&ctx->hhash_sha256, (uint8_t *) data, ST_SHA256_BLOCK_SIZE) != 0) {
be_bryan 0:b74591d5ab33 120 return; // Return error code
be_bryan 0:b74591d5ab33 121 }
be_bryan 0:b74591d5ab33 122 } else {
be_bryan 0:b74591d5ab33 123 if (HAL_HASHEx_SHA224_Accumulate(&ctx->hhash_sha256, (uint8_t *) data, ST_SHA256_BLOCK_SIZE) != 0) {
be_bryan 0:b74591d5ab33 124 return; // Return error code
be_bryan 0:b74591d5ab33 125 }
be_bryan 0:b74591d5ab33 126 }
be_bryan 0:b74591d5ab33 127
be_bryan 0:b74591d5ab33 128 if (st_sha256_save_hw_context(ctx) != 1) {
be_bryan 0:b74591d5ab33 129 return; // return HASH_BUSY timeout Error here
be_bryan 0:b74591d5ab33 130 }
be_bryan 0:b74591d5ab33 131 }
be_bryan 0:b74591d5ab33 132
be_bryan 0:b74591d5ab33 133 void mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen )
be_bryan 0:b74591d5ab33 134 {
be_bryan 0:b74591d5ab33 135 size_t currentlen = ilen;
be_bryan 0:b74591d5ab33 136 if (st_sha256_restore_hw_context(ctx) != 1) {
be_bryan 0:b74591d5ab33 137 return; // Return HASH_BUSY timout error here
be_bryan 0:b74591d5ab33 138 }
be_bryan 0:b74591d5ab33 139
be_bryan 0:b74591d5ab33 140 // store mechanism to accumulate ST_SHA256_BLOCK_SIZE bytes (512 bits) in the HW
be_bryan 0:b74591d5ab33 141 if (currentlen == 0) { // only change HW status is size if 0
be_bryan 0:b74591d5ab33 142 if(ctx->hhash_sha256.Phase == HAL_HASH_PHASE_READY) {
be_bryan 0:b74591d5ab33 143 /* Select the SHA256 or SHA224 mode and reset the HASH processor core, so that the HASH will be ready to compute
be_bryan 0:b74591d5ab33 144 the message digest of a new message */
be_bryan 0:b74591d5ab33 145 if (ctx->is224 == 0) {
be_bryan 0:b74591d5ab33 146 HASH->CR |= HASH_ALGOSELECTION_SHA256 | HASH_CR_INIT;
be_bryan 0:b74591d5ab33 147 } else {
be_bryan 0:b74591d5ab33 148 HASH->CR |= HASH_ALGOSELECTION_SHA224 | HASH_CR_INIT;
be_bryan 0:b74591d5ab33 149 }
be_bryan 0:b74591d5ab33 150 }
be_bryan 0:b74591d5ab33 151 ctx->hhash_sha256.Phase = HAL_HASH_PHASE_PROCESS;
be_bryan 0:b74591d5ab33 152 } else if (currentlen < (ST_SHA256_BLOCK_SIZE - ctx->sbuf_len)) {
be_bryan 0:b74591d5ab33 153 // only buffurize
be_bryan 0:b74591d5ab33 154 memcpy(ctx->sbuf + ctx->sbuf_len, input, currentlen);
be_bryan 0:b74591d5ab33 155 ctx->sbuf_len += currentlen;
be_bryan 0:b74591d5ab33 156 } else {
be_bryan 0:b74591d5ab33 157 // fill buffer and process it
be_bryan 0:b74591d5ab33 158 memcpy(ctx->sbuf + ctx->sbuf_len, input, (ST_SHA256_BLOCK_SIZE - ctx->sbuf_len));
be_bryan 0:b74591d5ab33 159 currentlen -= (ST_SHA256_BLOCK_SIZE - ctx->sbuf_len);
be_bryan 0:b74591d5ab33 160 mbedtls_sha256_process(ctx, ctx->sbuf);
be_bryan 0:b74591d5ab33 161 // Process every input as long as it is %64 bytes, ie 512 bits
be_bryan 0:b74591d5ab33 162 size_t iter = currentlen / ST_SHA256_BLOCK_SIZE;
be_bryan 0:b74591d5ab33 163 if (iter !=0) {
be_bryan 0:b74591d5ab33 164 if (ctx->is224 == 0) {
be_bryan 0:b74591d5ab33 165 if (HAL_HASHEx_SHA256_Accumulate(&ctx->hhash_sha256, (uint8_t *)(input + ST_SHA256_BLOCK_SIZE - ctx->sbuf_len), (iter * ST_SHA256_BLOCK_SIZE)) != 0) {
be_bryan 0:b74591d5ab33 166 return; // Return error code here
be_bryan 0:b74591d5ab33 167 }
be_bryan 0:b74591d5ab33 168 } else {
be_bryan 0:b74591d5ab33 169 if (HAL_HASHEx_SHA224_Accumulate(&ctx->hhash_sha256, (uint8_t *)(input + ST_SHA256_BLOCK_SIZE - ctx->sbuf_len), (iter * ST_SHA256_BLOCK_SIZE)) != 0) {
be_bryan 0:b74591d5ab33 170 return; // Return error code here
be_bryan 0:b74591d5ab33 171 }
be_bryan 0:b74591d5ab33 172 }
be_bryan 0:b74591d5ab33 173 }
be_bryan 0:b74591d5ab33 174 // sbuf is completely accumulated, now copy up to 63 remaining bytes
be_bryan 0:b74591d5ab33 175 ctx->sbuf_len = currentlen % ST_SHA256_BLOCK_SIZE;
be_bryan 0:b74591d5ab33 176 if (ctx->sbuf_len !=0) {
be_bryan 0:b74591d5ab33 177 memcpy(ctx->sbuf, input + ilen - ctx->sbuf_len, ctx->sbuf_len);
be_bryan 0:b74591d5ab33 178 }
be_bryan 0:b74591d5ab33 179 }
be_bryan 0:b74591d5ab33 180 if (st_sha256_save_hw_context(ctx) != 1) {
be_bryan 0:b74591d5ab33 181 return; // return HASH_BUSY timeout Error here
be_bryan 0:b74591d5ab33 182 }
be_bryan 0:b74591d5ab33 183 }
be_bryan 0:b74591d5ab33 184
be_bryan 0:b74591d5ab33 185 void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char output[32] )
be_bryan 0:b74591d5ab33 186 {
be_bryan 0:b74591d5ab33 187 if (st_sha256_restore_hw_context(ctx) != 1) {
be_bryan 0:b74591d5ab33 188 return; // Return HASH_BUSY timout error here
be_bryan 0:b74591d5ab33 189 }
be_bryan 0:b74591d5ab33 190 if (ctx->sbuf_len > 0) {
be_bryan 0:b74591d5ab33 191 if (ctx->is224 == 0) {
be_bryan 0:b74591d5ab33 192 if (HAL_HASHEx_SHA256_Accumulate(&ctx->hhash_sha256, ctx->sbuf, ctx->sbuf_len) != 0) {
be_bryan 0:b74591d5ab33 193 return; // Return error code here
be_bryan 0:b74591d5ab33 194 }
be_bryan 0:b74591d5ab33 195 } else {
be_bryan 0:b74591d5ab33 196 if (HAL_HASHEx_SHA224_Accumulate(&ctx->hhash_sha256, ctx->sbuf, ctx->sbuf_len) != 0) {
be_bryan 0:b74591d5ab33 197 return; // Return error code here
be_bryan 0:b74591d5ab33 198 }
be_bryan 0:b74591d5ab33 199 }
be_bryan 0:b74591d5ab33 200 }
be_bryan 0:b74591d5ab33 201 mbedtls_zeroize(ctx->sbuf, ST_SHA256_BLOCK_SIZE);
be_bryan 0:b74591d5ab33 202 ctx->sbuf_len = 0;
be_bryan 0:b74591d5ab33 203 __HAL_HASH_START_DIGEST();
be_bryan 0:b74591d5ab33 204
be_bryan 0:b74591d5ab33 205 if (ctx->is224 == 0) {
be_bryan 0:b74591d5ab33 206 if (HAL_HASHEx_SHA256_Finish(&ctx->hhash_sha256, output, 10) != 0) {
be_bryan 0:b74591d5ab33 207 return; // Return error code here
be_bryan 0:b74591d5ab33 208 }
be_bryan 0:b74591d5ab33 209 } else {
be_bryan 0:b74591d5ab33 210 if (HAL_HASHEx_SHA224_Finish(&ctx->hhash_sha256, output, 10) != 0) {
be_bryan 0:b74591d5ab33 211 return; // Return error code here
be_bryan 0:b74591d5ab33 212 }
be_bryan 0:b74591d5ab33 213 }
be_bryan 0:b74591d5ab33 214 if (st_sha256_save_hw_context(ctx) != 1) {
be_bryan 0:b74591d5ab33 215 return; // return HASH_BUSY timeout Error here
be_bryan 0:b74591d5ab33 216 }
be_bryan 0:b74591d5ab33 217 }
be_bryan 0:b74591d5ab33 218
be_bryan 0:b74591d5ab33 219 #endif /*MBEDTLS_SHA256_ALT*/