void sm3_update(sm3_ctx_t *ctx, const unsigned char* data, size_t data_len) { if (ctx->num) { unsigned int left = SM3_BLOCK_SIZE - ctx->num; if (data_len < left) { memcpy(ctx->block + ctx->num, data, data_len); ctx->num += data_len; return; } else { memcpy(ctx->block + ctx->num, data, left); sm3_compress(ctx->digest, ctx->block); ctx->nblocks++; data += left; data_len -= left; } } while (data_len >= SM3_BLOCK_SIZE) { sm3_compress(ctx->digest, data); ctx->nblocks++; data += SM3_BLOCK_SIZE; data_len -= SM3_BLOCK_SIZE; } ctx->num = data_len; if (data_len) { memcpy(ctx->block, data, data_len); } }
int sm3_final(sm3_ctx_t *ctx, unsigned char *digest) { if (ctx == NULL) return 0; int i; uint32_t *pdigest = (uint32_t *)digest; uint32_t *count = (uint32_t *)(ctx->block + SM3_BLOCK_SIZE - 8); ctx->block[ctx->num] = 0x80; if (ctx->num + 9 <= SM3_BLOCK_SIZE) { memset(ctx->block + ctx->num + 1, 0, SM3_BLOCK_SIZE - ctx->num - 9); } else { memset(ctx->block + ctx->num + 1, 0, SM3_BLOCK_SIZE - ctx->num - 1); sm3_compress(ctx->digest, ctx->block); memset(ctx->block, 0, SM3_BLOCK_SIZE - 8); } count[0] = cpu_to_be32((ctx->nblocks) >> 23); count[1] = cpu_to_be32((ctx->nblocks << 9) + (ctx->num << 3)); sm3_compress(ctx->digest, ctx->block); for (i = 0; i < sizeof(ctx->digest) / sizeof(ctx->digest[0]); i++) { pdigest[i] = cpu_to_be32(ctx->digest[i]); } return 1; }
static void sm3_transform(struct sm3_state *sst, u8 const *src) { unsigned int w[68]; unsigned int wt[64]; sm3_expand((u32 *)src, w, wt); sm3_compress(w, wt, sst->state); memzero_explicit(w, sizeof(w)); memzero_explicit(wt, sizeof(wt)); }