Commit b86ced88 authored by Eric Biggers's avatar Eric Biggers
Browse files

lib/crypto: sha256: Make library API use strongly-typed contexts



Currently the SHA-224 and SHA-256 library functions can be mixed
arbitrarily, even in ways that are incorrect, for example using
sha224_init() and sha256_final().  This is because they operate on the
same structure, sha256_state.

Introduce stronger typing, as I did for SHA-384 and SHA-512.

Also as I did for SHA-384 and SHA-512, use the names *_ctx instead of
*_state.  The *_ctx names have the following small benefits:

- They're shorter.
- They avoid an ambiguity with the compression function state.
- They're consistent with the well-known OpenSSL API.
- Users usually name the variable 'sctx' anyway, which suggests that
  *_ctx would be the more natural name for the actual struct.

Therefore: update the SHA-224 and SHA-256 APIs, implementation, and
calling code accordingly.

In the new structs, also strongly-type the compression function state.

Acked-by: default avatarArd Biesheuvel <ardb@kernel.org>
Link: https://lore.kernel.org/r/20250630160645.3198-7-ebiggers@kernel.org


Signed-off-by: default avatarEric Biggers <ebiggers@kernel.org>
parent 6fa4b292
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -20,14 +20,14 @@ struct kexec_sha_region purgatory_sha_regions[KEXEC_SEGMENT_MAX] __section(".kex
static int verify_sha256_digest(void)
{
	struct kexec_sha_region *ptr, *end;
	struct sha256_state ss;
	struct sha256_ctx sctx;
	u8 digest[SHA256_DIGEST_SIZE];

	sha256_init(&ss);
	sha256_init(&sctx);
	end = purgatory_sha_regions + ARRAY_SIZE(purgatory_sha_regions);
	for (ptr = purgatory_sha_regions; ptr < end; ptr++)
		sha256_update(&ss, (uint8_t *)(ptr->start), ptr->len);
	sha256_final(&ss, digest);
		sha256_update(&sctx, (uint8_t *)(ptr->start), ptr->len);
	sha256_final(&sctx, digest);
	if (memcmp(digest, purgatory_sha256_digest, sizeof(digest)) != 0)
		return 1;
	return 0;
+1 −1
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@ int verify_sha256_digest(void)
{
	struct kexec_sha_region *ptr, *end;
	u8 digest[SHA256_DIGEST_SIZE];
	struct sha256_state sctx;
	struct sha256_ctx sctx;

	sha256_init(&sctx);
	end = purgatory_sha_regions + ARRAY_SIZE(purgatory_sha_regions);
+1 −1
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@ static int verify_sha256_digest(void)
{
	struct kexec_sha_region *ptr, *end;
	u8 digest[SHA256_DIGEST_SIZE];
	struct sha256_state sctx;
	struct sha256_ctx sctx;

	sha256_init(&sctx);
	end = purgatory_sha_regions + ARRAY_SIZE(purgatory_sha_regions);
+8 −8
Original line number Diff line number Diff line
@@ -137,24 +137,24 @@ static int crypto_sha224_final_lib(struct shash_desc *desc, u8 *out)

static int crypto_sha256_import_lib(struct shash_desc *desc, const void *in)
{
	struct sha256_state *sctx = shash_desc_ctx(desc);
	struct __sha256_ctx *sctx = shash_desc_ctx(desc);
	const u8 *p = in;

	memcpy(sctx, p, sizeof(*sctx));
	p += sizeof(*sctx);
	sctx->count += *p;
	sctx->bytecount += *p;
	return 0;
}

static int crypto_sha256_export_lib(struct shash_desc *desc, void *out)
{
	struct sha256_state *sctx0 = shash_desc_ctx(desc);
	struct sha256_state sctx = *sctx0;
	struct __sha256_ctx *sctx0 = shash_desc_ctx(desc);
	struct __sha256_ctx sctx = *sctx0;
	unsigned int partial;
	u8 *p = out;

	partial = sctx.count % SHA256_BLOCK_SIZE;
	sctx.count -= partial;
	partial = sctx.bytecount % SHA256_BLOCK_SIZE;
	sctx.bytecount -= partial;
	memcpy(p, &sctx, sizeof(sctx));
	p += sizeof(sctx);
	*p = partial;
@@ -201,7 +201,7 @@ static struct shash_alg algs[] = {
		.update			= crypto_sha256_update_lib,
		.final			= crypto_sha256_final_lib,
		.digest			= crypto_sha256_digest_lib,
		.descsize		= sizeof(struct sha256_state),
		.descsize		= sizeof(struct sha256_ctx),
		.statesize		= sizeof(struct crypto_sha256_state) +
					  SHA256_BLOCK_SIZE + 1,
		.import			= crypto_sha256_import_lib,
@@ -216,7 +216,7 @@ static struct shash_alg algs[] = {
		.init			= crypto_sha224_init,
		.update			= crypto_sha256_update_lib,
		.final			= crypto_sha224_final_lib,
		.descsize		= sizeof(struct sha256_state),
		.descsize		= sizeof(struct sha224_ctx),
		.statesize		= sizeof(struct crypto_sha256_state) +
					  SHA256_BLOCK_SIZE + 1,
		.import			= crypto_sha256_import_lib,
+6 −6
Original line number Diff line number Diff line
@@ -390,7 +390,7 @@ static int tpm2_create_primary(struct tpm_chip *chip, u32 hierarchy,
 * on every operation, so we weld the hmac init and final functions in
 * here to give it the same usage characteristics as a regular hash
 */
static void tpm2_hmac_init(struct sha256_state *sctx, u8 *key, u32 key_len)
static void tpm2_hmac_init(struct sha256_ctx *sctx, u8 *key, u32 key_len)
{
	u8 pad[SHA256_BLOCK_SIZE];
	int i;
@@ -406,7 +406,7 @@ static void tpm2_hmac_init(struct sha256_state *sctx, u8 *key, u32 key_len)
	sha256_update(sctx, pad, sizeof(pad));
}

static void tpm2_hmac_final(struct sha256_state *sctx, u8 *key, u32 key_len,
static void tpm2_hmac_final(struct sha256_ctx *sctx, u8 *key, u32 key_len,
			    u8 *out)
{
	u8 pad[SHA256_BLOCK_SIZE];
@@ -440,7 +440,7 @@ static void tpm2_KDFa(u8 *key, u32 key_len, const char *label, u8 *u,
	const __be32 bits = cpu_to_be32(bytes * 8);

	while (bytes > 0) {
		struct sha256_state sctx;
		struct sha256_ctx sctx;
		__be32 c = cpu_to_be32(counter);

		tpm2_hmac_init(&sctx, key, key_len);
@@ -467,7 +467,7 @@ static void tpm2_KDFa(u8 *key, u32 key_len, const char *label, u8 *u,
static void tpm2_KDFe(u8 z[EC_PT_SZ], const char *str, u8 *pt_u, u8 *pt_v,
		      u8 *out)
{
	struct sha256_state sctx;
	struct sha256_ctx sctx;
	/*
	 * this should be an iterative counter, but because we know
	 *  we're only taking 32 bytes for the point using a sha256
@@ -592,7 +592,7 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf)
	u8 *hmac = NULL;
	u32 attrs;
	u8 cphash[SHA256_DIGEST_SIZE];
	struct sha256_state sctx;
	struct sha256_ctx sctx;

	if (!auth)
		return;
@@ -750,7 +750,7 @@ int tpm_buf_check_hmac_response(struct tpm_chip *chip, struct tpm_buf *buf,
	off_t offset_s, offset_p;
	u8 rphash[SHA256_DIGEST_SIZE];
	u32 attrs, cc;
	struct sha256_state sctx;
	struct sha256_ctx sctx;
	u16 tag = be16_to_cpu(head->tag);
	int parm_len, len, i, handles;

Loading