brintos

brintos / linux-shallow public Read only

0
0
Text · 2.5 KiB · b33ed39 Raw
113 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/*3 * sm3_base.h - core logic for SM3 implementations4 *5 * Copyright (C) 2017 ARM Limited or its affiliates.6 * Written by Gilad Ben-Yossef <gilad@benyossef.com>7 */8 9#ifndef _CRYPTO_SM3_BASE_H10#define _CRYPTO_SM3_BASE_H11 12#include <crypto/internal/hash.h>13#include <crypto/sm3.h>14#include <linux/crypto.h>15#include <linux/module.h>16#include <linux/string.h>17#include <linux/unaligned.h>18 19typedef void (sm3_block_fn)(struct sm3_state *sst, u8 const *src, int blocks);20 21static inline int sm3_base_init(struct shash_desc *desc)22{23	struct sm3_state *sctx = shash_desc_ctx(desc);24 25	sctx->state[0] = SM3_IVA;26	sctx->state[1] = SM3_IVB;27	sctx->state[2] = SM3_IVC;28	sctx->state[3] = SM3_IVD;29	sctx->state[4] = SM3_IVE;30	sctx->state[5] = SM3_IVF;31	sctx->state[6] = SM3_IVG;32	sctx->state[7] = SM3_IVH;33	sctx->count = 0;34 35	return 0;36}37 38static inline int sm3_base_do_update(struct shash_desc *desc,39				      const u8 *data,40				      unsigned int len,41				      sm3_block_fn *block_fn)42{43	struct sm3_state *sctx = shash_desc_ctx(desc);44	unsigned int partial = sctx->count % SM3_BLOCK_SIZE;45 46	sctx->count += len;47 48	if (unlikely((partial + len) >= SM3_BLOCK_SIZE)) {49		int blocks;50 51		if (partial) {52			int p = SM3_BLOCK_SIZE - partial;53 54			memcpy(sctx->buffer + partial, data, p);55			data += p;56			len -= p;57 58			block_fn(sctx, sctx->buffer, 1);59		}60 61		blocks = len / SM3_BLOCK_SIZE;62		len %= SM3_BLOCK_SIZE;63 64		if (blocks) {65			block_fn(sctx, data, blocks);66			data += blocks * SM3_BLOCK_SIZE;67		}68		partial = 0;69	}70	if (len)71		memcpy(sctx->buffer + partial, data, len);72 73	return 0;74}75 76static inline int sm3_base_do_finalize(struct shash_desc *desc,77					sm3_block_fn *block_fn)78{79	const int bit_offset = SM3_BLOCK_SIZE - sizeof(__be64);80	struct sm3_state *sctx = shash_desc_ctx(desc);81	__be64 *bits = (__be64 *)(sctx->buffer + bit_offset);82	unsigned int partial = sctx->count % SM3_BLOCK_SIZE;83 84	sctx->buffer[partial++] = 0x80;85	if (partial > bit_offset) {86		memset(sctx->buffer + partial, 0x0, SM3_BLOCK_SIZE - partial);87		partial = 0;88 89		block_fn(sctx, sctx->buffer, 1);90	}91 92	memset(sctx->buffer + partial, 0x0, bit_offset - partial);93	*bits = cpu_to_be64(sctx->count << 3);94	block_fn(sctx, sctx->buffer, 1);95 96	return 0;97}98 99static inline int sm3_base_finish(struct shash_desc *desc, u8 *out)100{101	struct sm3_state *sctx = shash_desc_ctx(desc);102	__be32 *digest = (__be32 *)out;103	int i;104 105	for (i = 0; i < SM3_DIGEST_SIZE / sizeof(__be32); i++)106		put_unaligned_be32(sctx->state[i], digest++);107 108	memzero_explicit(sctx, sizeof(*sctx));109	return 0;110}111 112#endif /* _CRYPTO_SM3_BASE_H */113