aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorareviu <areviu.info@gmail.com>2017-11-16 21:29:04 +0000
committerareviu <areviu.info@gmail.com>2017-11-16 21:29:04 +0000
commitb8bb3e95c4d72eae77c5e59a24a72b34f7e7bfe1 (patch)
tree73365da89625a56f071023eaa3ace5cbc049848d
parentbff0267ac47b655c0bfd7f874a3c27263adc1185 (diff)
downloadChibiOS-b8bb3e95c4d72eae77c5e59a24a72b34f7e7bfe1.tar.gz
ChibiOS-b8bb3e95c4d72eae77c5e59a24a72b34f7e7bfe1.tar.bz2
ChibiOS-b8bb3e95c4d72eae77c5e59a24a72b34f7e7bfe1.zip
added sha (polling)
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@11025 35acf78f-673a-0410-8e92-d51de3d6d3f4
-rw-r--r--os/hal/ports/SAMA/LLD/CRYPTOv1/driver.mk3
-rw-r--r--os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.h1
-rw-r--r--os/hal/ports/SAMA/LLD/CRYPTOv1/sama_sha_lld.c331
-rw-r--r--os/hal/ports/SAMA/LLD/CRYPTOv1/sama_sha_lld.h31
-rw-r--r--os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.h14
5 files changed, 379 insertions, 1 deletions
diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/driver.mk b/os/hal/ports/SAMA/LLD/CRYPTOv1/driver.mk
index 120be44b7..9673bb649 100644
--- a/os/hal/ports/SAMA/LLD/CRYPTOv1/driver.mk
+++ b/os/hal/ports/SAMA/LLD/CRYPTOv1/driver.mk
@@ -1,6 +1,7 @@
PLATFORMSRC +=$(CHIBIOS)/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.c \
$(CHIBIOS)/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_aes_lld.c \
- $(CHIBIOS)/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_tdes_lld.c
+ $(CHIBIOS)/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_tdes_lld.c \
+ $(CHIBIOS)/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_sha_lld.c
diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.h b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.h
index 5636d32b3..9134f189c 100644
--- a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.h
+++ b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_crypto_lld.h
@@ -51,6 +51,7 @@ extern uint32_t key0_buffer[HAL_CRY_MAX_KEY_SIZE/4];
#include "sama_aes_lld.h"
#include "sama_tdes_lld.h"
+#include "sama_sha_lld.h"
#endif /* HAL_USE_CRY */
diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_sha_lld.c b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_sha_lld.c
new file mode 100644
index 000000000..8f432e1e6
--- /dev/null
+++ b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_sha_lld.c
@@ -0,0 +1,331 @@
+/*
+ ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
+
+ 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.
+*/
+#include "hal.h"
+#include <string.h>
+#if (HAL_USE_CRY == TRUE) || defined(__DOXYGEN__)
+
+#include "sama_crypto_lld.h"
+
+#define SHA_MAX_PADDING_LEN (2 * 128)
+#define SHA_UPDATE_LEN (128 * 1024)
+
+struct sha_data {
+ uint32_t remaining;
+ uint32_t processed;
+ uint32_t block_size;
+ uint32_t output_size;
+ shadalgo_t algo;
+};
+
+static uint8_t sha_buffer[SHA_MAX_PADDING_LEN];
+
+static uint32_t shaOutputSize(shadalgo_t algo);
+static uint32_t shadPaddedMessSize(uint8_t mode, uint32_t len);
+static uint8_t shaBlockSize(shadalgo_t algo);
+static void loadData(const uint8_t* data, int len);
+static void readData(const uint8_t* data, int len);
+static uint32_t processBlock(const uint8_t* data, uint32_t len, uint32_t block_size);
+static void updatePollingMode(struct sha_data *shadata,const uint8_t* data, uint32_t data_size);
+static void updateDMA(struct sha_data *shadata,const uint8_t* data, uint32_t data_size);
+
+static uint32_t fillPadding(struct sha_data *shadata, uint32_t len, uint8_t* buffer);
+
+static inline uint32_t min_u32(uint32_t a, uint32_t b)
+{
+ return a < b ? a : b;
+}
+
+
+
+
+
+
+int sha_finish(struct sha_data *shadata,const uint8_t* buffer,uint32_t buffer_size)
+{
+
+ uint32_t padding_len;
+
+ if (buffer_size < shadata->output_size)
+ return -1;
+
+ //pad data for the end of the buffer
+ padding_len = fillPadding(shadata,
+ shadata->processed + shadata->remaining,
+ &sha_buffer[shadata->remaining]
+ );
+
+ processBlock(sha_buffer, shadata->remaining + padding_len, shadata->block_size);
+
+ readData(buffer, buffer_size);
+
+ return 0;
+}
+
+cryerror_t sama_sha_lld_process(CRYDriver *cryp,
+ shaparams_t *params,
+ const uint8_t *in,
+ uint8_t *out,
+ size_t indata_len,
+ size_t out_size
+ )
+{
+ uint32_t algoregval;
+ struct sha_data shadata;
+ //uint8_t *data_in;
+
+ if (!(cryp->enabledPer & SHA_PER)) {
+ cryp->enabledPer |= SHA_PER;
+ pmcEnableSHA();
+ }
+
+ shadata.processed = 0;
+ shadata.remaining = 0;
+ shadata.output_size = shaOutputSize(params->algo);
+ shadata.block_size = shaBlockSize(params->algo);
+ shadata.algo = params->algo;
+
+ if (shadata.output_size == 0) {
+ return CRY_ERR_INV_ALGO;
+ }
+
+ switch (params->algo) {
+ case CRY_SHA_1:
+ algoregval = SHA_MR_ALGO_SHA1;
+ break;
+ case CRY_SHA_224:
+ algoregval = SHA_MR_ALGO_SHA224;
+ break;
+ case CRY_SHA_256:
+ algoregval = SHA_MR_ALGO_SHA256;
+ break;
+ #ifdef SHA_MR_ALGO_SHA384
+ case CRY_SHA_384:
+ algoregval = SHA_MR_ALGO_SHA384;
+ break;
+ #endif
+ #ifdef SHA_MR_ALGO_SHA512
+ case CRY_SHA_512:
+ algoregval = SHA_MR_ALGO_SHA512;
+ break;
+ #endif
+ default:
+ return CRY_ERR_INV_ALGO;
+ }
+
+ //soft reset
+ SHA->SHA_CR = SHA_CR_SWRST;
+ //configure
+ SHA->SHA_MR = algoregval | SHA_MR_SMOD_MANUAL_START | SHA_MR_PROCDLY_LONGEST;
+
+ //enable interrupt
+ SHA->SHA_IER = SHA_IER_DATRDY;
+
+ uint32_t buf_in_size;
+ uint8_t *p=in;
+
+ while (indata_len) {
+ buf_in_size = min_u32(indata_len, SHA_UPDATE_LEN);
+
+ //First block
+ if (!shadata.processed) {
+ SHA->SHA_CR = SHA_CR_FIRST;
+ }
+
+ if (cryp->config->transfer_mode == TRANSFER_POLLING)
+ updatePollingMode(&shadata, in, buf_in_size);
+ else
+ updateDMA(&shadata, in, buf_in_size);
+
+ p += buf_in_size;
+ indata_len -= buf_in_size;
+ }
+
+ sha_finish(&shadata, out, out_size);
+
+
+
+ return CRY_NOERROR;
+}
+
+
+static uint32_t shaOutputSize(shadalgo_t algo)
+{
+ switch (algo) {
+ case CRY_SHA_1:
+ return 20;
+ case CRY_SHA_224:
+ return 28;
+ case CRY_SHA_256:
+ return 32;
+ case CRY_SHA_384:
+ return 48;
+ case CRY_SHA_512:
+ return 64;
+ default:
+ return 0;
+ }
+}
+
+static uint32_t shadPaddedMessSize(uint8_t mode, uint32_t len)
+{
+ uint32_t k;
+
+ switch (mode) {
+ case CRY_SHA_1:
+ case CRY_SHA_224:
+ case CRY_SHA_256:
+ k = (512 + 448 - (((len * 8) % 512) + 1)) % 512;
+ len += (k - 7) / 8 + 9;
+ break;
+ case CRY_SHA_384:
+ case CRY_SHA_512:
+ k = (1024 + 896 - (((len * 8) % 1024) + 1)) % 1024;
+ len += (k - 7) / 8 + 17;
+ break;
+ }
+ return len;
+}
+
+static uint8_t shaBlockSize(shadalgo_t algo)
+{
+ if ( (algo == CRY_SHA_384) || (algo == CRY_SHA_512) ) {
+ return 128;
+ }
+
+ return 64;
+}
+
+
+static void loadData(const uint8_t* data, int len)
+{
+ int i;
+ int32_t value;
+
+ for (i = 0; i < (len / 4) && i < 32; i++) {
+ memcpy(&value, &data[i * 4], 4);
+ if (i < 16)
+ SHA->SHA_IDATAR[i] = value;
+ else
+ SHA->SHA_IODATAR[i - 16] = value;
+ }
+}
+static void readData(const uint8_t* data, int len)
+{
+ int i;
+ int32_t value;
+
+ for (i = 0; i < (len / 4) && i < 16; i++) {
+ value = SHA->SHA_IODATAR[i];
+ memcpy(&data[i * 4], &value, 4);
+ }
+}
+
+
+static uint32_t processBlock(const uint8_t* data, uint32_t len, uint32_t block_size)
+{
+ uint32_t processed = 0;
+
+ while ((len - processed) >= block_size) {
+
+ // load data in the sha input registers
+ loadData(&data[processed], block_size);
+
+ SHA->SHA_CR = SHA_CR_START;
+
+ // Wait for data ready
+ while ((SHA->SHA_ISR & SHA_ISR_DATRDY) == 0);
+
+ processed += block_size;
+ }
+
+ return processed;
+}
+
+static void updateDMA(struct sha_data *shadata,const uint8_t* data, uint32_t data_size)
+{
+ (void)shadata;
+ (void)data;
+ (void)data_size;
+}
+static void updatePollingMode(struct sha_data *shadata,const uint8_t* data, uint32_t data_size)
+{
+ uint32_t i;
+ uint32_t processed;
+
+ //check data from previous update
+ if (shadata->remaining) {
+ //complete previous data
+ uint32_t complement = min_u32(data_size, shadata->block_size - shadata->remaining);
+ memcpy(&sha_buffer[shadata->remaining], data, complement);
+ shadata->remaining += complement;
+ data += complement;
+ data_size -= complement;
+
+ //if data is complete process the block
+ if (shadata->remaining == shadata->block_size) {
+ processBlock(sha_buffer, shadata->remaining, shadata->block_size);
+
+ shadata->processed += shadata->block_size;
+ shadata->remaining = 0;
+ } else {
+ //complete processing in the next update/
+ return;
+ }
+ }
+
+ // Process blocks
+ processed = processBlock(data, data_size, shadata->block_size);
+ shadata->processed += processed;
+
+ //check remaining data and process
+ shadata->remaining = data_size - processed;
+ if (shadata->remaining)
+ {
+ for (i=0;i<shadata->remaining;i++)
+ sha_buffer[i] = data[processed+i];
+ }
+}
+
+static uint32_t fillPadding(struct sha_data *shadata, uint32_t len, uint8_t* buffer)
+{
+ uint32_t padding_len = shadPaddedMessSize(shadata->algo, len) - len;
+ uint32_t k = padding_len - 9;
+
+ osalDbgAssert( padding_len <= (SHA_MAX_PADDING_LEN - shadata->remaining),
+ "invalid buffer size");
+
+
+ // Append "1" bit and seven "0" bits to the end of the message
+ *buffer++ = 0x80;
+ // Add k "0" bits
+ memset(buffer, 0, k);
+ buffer += k;
+ // length is at the end of message (64-bit)
+ *buffer++ = 0;
+ *buffer++ = 0;
+ *buffer++ = 0;
+ *buffer++ = (len >> 29) & 0xFF;
+ *buffer++ = (len >> 21) & 0xFF;
+ *buffer++ = (len >> 13) & 0xFF;
+ *buffer++ = (len >> 5) & 0xFF;
+ *buffer++ = (len << 3) & 0xFF;
+ return padding_len;
+}
+#endif /* HAL_USE_CRY */
+
+/** @} */
+
+
diff --git a/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_sha_lld.h b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_sha_lld.h
new file mode 100644
index 000000000..f2702fe97
--- /dev/null
+++ b/os/hal/ports/SAMA/LLD/CRYPTOv1/sama_sha_lld.h
@@ -0,0 +1,31 @@
+/*
+ ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
+
+ 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.
+*/
+#ifndef CRYPTOLIB_LLD_SAMA_SHA_H_
+#define CRYPTOLIB_LLD_SAMA_SHA_H_
+
+
+
+cryerror_t sama_sha_lld_process(CRYDriver *cryp,
+ shaparams_t *params,
+ const uint8_t *in,
+ uint8_t *out,
+ size_t indata_len,
+ size_t out_size
+ );
+
+
+
+#endif /* CRYPTOLIB_LLD_SAMA_SHA_H_ */
diff --git a/os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.h b/os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.h
index d9ef51f30..029b4d83c 100644
--- a/os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.h
+++ b/os/hal/ports/SAMA/SAMA5D2x/hal_crypto_lld.h
@@ -94,6 +94,20 @@ typedef enum {
}aesciphersize_t;
+typedef enum {
+ CRY_SHA_1,
+ CRY_SHA_224,
+ CRY_SHA_256,
+ CRY_SHA_384,
+ CRY_SHA_512,
+}shadalgo_t;
+
+typedef struct
+{
+ shadalgo_t algo;
+
+}shaparams_t;
+
/**
* @brief CRY key identifier type.
*/