arch/s390/crypto/hmac_s390.c

Source file repositories/reference/linux-study-clean/arch/s390/crypto/hmac_s390.c

File Facts

System
Linux kernel
Corpus path
arch/s390/crypto/hmac_s390.c
Extension
.c
Size
10657 bytes
Lines
427
Domain
Architecture Layer
Bucket
arch/s390
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

struct s390_hmac_ctx {
	u8 key[MAX_BLOCK_SIZE];
};

union s390_kmac_gr0 {
	unsigned long reg;
	struct {
		unsigned long		: 48;
		unsigned long ikp	:  1;
		unsigned long iimp	:  1;
		unsigned long ccup	:  1;
		unsigned long		:  6;
		unsigned long fc	:  7;
	};
};

struct s390_kmac_sha2_ctx {
	u8 param[MAX_DIGEST_SIZE + MAX_IMBL_SIZE + MAX_BLOCK_SIZE];
	union s390_kmac_gr0 gr0;
	u64 buflen[2];
};

/*
 * kmac_sha2_set_imbl - sets the input message bit-length based on the blocksize
 */
static inline void kmac_sha2_set_imbl(u8 *param, u64 buflen_lo,
				      u64 buflen_hi, unsigned int blocksize)
{
	u8 *imbl = param + SHA2_IMBL_OFFSET(blocksize);

	switch (blocksize) {
	case SHA256_BLOCK_SIZE:
		*(u64 *)imbl = buflen_lo * BITS_PER_BYTE;
		break;
	case SHA512_BLOCK_SIZE:
		*(u128 *)imbl = (((u128)buflen_hi << 64) + buflen_lo) << 3;
		break;
	default:
		break;
	}
}

static int hash_data(const u8 *in, unsigned int inlen,
		     u8 *digest, unsigned int digestsize, bool final)
{
	unsigned long func;
	union {
		struct sha256_paramblock {
			u32 h[8];
			u64 mbl;
		} sha256;
		struct sha512_paramblock {
			u64 h[8];
			u128 mbl;
		} sha512;
	} __packed param;

#define PARAM_INIT(x, y, z)		   \
	param.sha##x.h[0] = SHA##y ## _H0; \
	param.sha##x.h[1] = SHA##y ## _H1; \
	param.sha##x.h[2] = SHA##y ## _H2; \
	param.sha##x.h[3] = SHA##y ## _H3; \
	param.sha##x.h[4] = SHA##y ## _H4; \
	param.sha##x.h[5] = SHA##y ## _H5; \
	param.sha##x.h[6] = SHA##y ## _H6; \
	param.sha##x.h[7] = SHA##y ## _H7; \
	param.sha##x.mbl = (z)

	switch (digestsize) {
	case SHA224_DIGEST_SIZE:
		func = final ? CPACF_KLMD_SHA_256 : CPACF_KIMD_SHA_256;
		PARAM_INIT(256, 224, inlen * 8);
		if (!final)
			digestsize = SHA256_DIGEST_SIZE;
		break;
	case SHA256_DIGEST_SIZE:
		func = final ? CPACF_KLMD_SHA_256 : CPACF_KIMD_SHA_256;
		PARAM_INIT(256, 256, inlen * 8);
		break;
	case SHA384_DIGEST_SIZE:
		func = final ? CPACF_KLMD_SHA_512 : CPACF_KIMD_SHA_512;
		PARAM_INIT(512, 384, inlen * 8);
		if (!final)
			digestsize = SHA512_DIGEST_SIZE;
		break;
	case SHA512_DIGEST_SIZE:
		func = final ? CPACF_KLMD_SHA_512 : CPACF_KIMD_SHA_512;
		PARAM_INIT(512, 512, inlen * 8);
		break;
	default:

Annotation

Implementation Notes