void cc3200_hash_update(struct cc3200_hash_ctx *ctx, const uint8_t *data, uint32_t len) { if (ctx->block_len > 0) { uint32_t block_remain = CC3200_HASH_BLOCK_SIZE - ctx->block_len; if (block_remain > len) block_remain = len; memcpy(ctx->block + ctx->block_len, data, block_remain); ctx->block_len += block_remain; data += block_remain; len -= block_remain; if (ctx->block_len < CC3200_HASH_BLOCK_SIZE) return; } const uint32_t to_hash = (((uint32_t) ctx->block_len) + len) & ~(CC3200_HASH_BLOCK_SIZE - 1); if (to_hash > 0) { vPortEnterCritical(); init_engine(ctx, 0); HWREG(SHAMD5_BASE + SHAMD5_O_LENGTH) = to_hash; if (ctx->block_len == CC3200_HASH_BLOCK_SIZE) { while ( !(HWREG(SHAMD5_BASE + SHAMD5_O_IRQSTATUS) & SHAMD5_INT_INPUT_READY)) ; uint32_t *p = (uint32_t *) ctx->block; for (int i = 0; i < CC3200_HASH_BLOCK_SIZE; i += 4) { HWREG(SHAMD5_BASE + SHAMD5_O_DATA0_IN + i) = *p++; } } while (len >= CC3200_HASH_BLOCK_SIZE) { while ( !(HWREG(SHAMD5_BASE + SHAMD5_O_IRQSTATUS) & SHAMD5_INT_INPUT_READY)) ; for (int i = 0; i < CC3200_HASH_BLOCK_SIZE; i += 4) { HWREG(SHAMD5_BASE + SHAMD5_O_DATA0_IN + i) = *((uint32_t *) data); data += 4; len -= 4; } } while (!(HWREG(SHAMD5_BASE + SHAMD5_O_IRQSTATUS) & SHAMD5_INT_OUTPUT_READY)) ; MAP_SHAMD5ResultRead(SHAMD5_BASE, (uint8_t *) ctx->digest); /* Must read count register to finish the round. */ HWREG(SHAMD5_BASE + SHAMD5_O_DIGEST_COUNT); MAP_PRCMPeripheralClkDisable(PRCM_DTHE, PRCM_RUN_MODE_CLK); vPortExitCritical(); } memcpy(ctx->block, data, len); ctx->block_len = len; }
void cc3200_hash_final(struct cc3200_hash_ctx *ctx, uint8_t *digest) { vPortEnterCritical(); init_engine(ctx, SHAMD5_MODE_CLOSE_HASH); HWREG(SHAMD5_BASE + SHAMD5_O_LENGTH) = ctx->block_len; int bl = ctx->block_len; int i = 0; uint32_t *p = (uint32_t *) ctx->block; while (bl - i > 4) { HWREG(SHAMD5_BASE + SHAMD5_O_DATA0_IN + i) = *p++; i += 4; } if (i < bl) { for (int j = bl; j % 4 != 0; j++) ctx->block[j] = 0; HWREG(SHAMD5_BASE + SHAMD5_O_DATA0_IN + i) = *p; } while (!(HWREG(SHAMD5_BASE + SHAMD5_O_IRQSTATUS) & SHAMD5_INT_OUTPUT_READY)) ; MAP_SHAMD5ResultRead(SHAMD5_BASE, digest); /* Must read count register to finish the round. */ HWREG(SHAMD5_BASE + SHAMD5_O_DIGEST_COUNT); MAP_PRCMPeripheralClkDisable(PRCM_DTHE, PRCM_RUN_MODE_CLK); vPortExitCritical(); }
void HASH_SHAMD5Read (uint8_t *hash) { // wait for the output to be ready while((HWREG(SHAMD5_BASE + SHAMD5_O_IRQSTATUS) & SHAMD5_INT_OUTPUT_READY) == 0); // read the result MAP_SHAMD5ResultRead(SHAMD5_BASE, hash); }