arch/s390/crypto/aes_s390.c

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

File Facts

System
Linux kernel
Corpus path
arch/s390/crypto/aes_s390.c
Extension
.c
Size
27730 bytes
Lines
1047
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_aes_ctx {
	u8 key[AES_MAX_KEY_SIZE];
	int key_len;
	unsigned long fc;
	union {
		struct crypto_skcipher *skcipher;
	} fallback;
};

struct s390_xts_ctx {
	union {
		u8 keys[64];
		struct {
			u8 key[32];
			u8 pcc_key[32];
		};
	};
	int key_len;
	unsigned long fc;
	struct crypto_skcipher *fallback;
};

struct gcm_sg_walk {
	struct scatter_walk walk;
	unsigned int walk_bytes;
	unsigned int walk_bytes_remain;
	u8 buf[AES_BLOCK_SIZE];
	unsigned int buf_bytes;
	u8 *ptr;
	unsigned int nbytes;
};

static int setkey_fallback_skcipher(struct crypto_skcipher *tfm, const u8 *key,
				    unsigned int len)
{
	struct s390_aes_ctx *sctx = crypto_skcipher_ctx(tfm);

	crypto_skcipher_clear_flags(sctx->fallback.skcipher,
				    CRYPTO_TFM_REQ_MASK);
	crypto_skcipher_set_flags(sctx->fallback.skcipher,
				  crypto_skcipher_get_flags(tfm) &
				  CRYPTO_TFM_REQ_MASK);
	return crypto_skcipher_setkey(sctx->fallback.skcipher, key, len);
}

static int fallback_skcipher_crypt(struct s390_aes_ctx *sctx,
				   struct skcipher_request *req,
				   unsigned long modifier)
{
	struct skcipher_request *subreq = skcipher_request_ctx(req);

	*subreq = *req;
	skcipher_request_set_tfm(subreq, sctx->fallback.skcipher);
	return (modifier & CPACF_DECRYPT) ?
		crypto_skcipher_decrypt(subreq) :
		crypto_skcipher_encrypt(subreq);
}

static int ecb_aes_set_key(struct crypto_skcipher *tfm, const u8 *in_key,
			   unsigned int key_len)
{
	struct s390_aes_ctx *sctx = crypto_skcipher_ctx(tfm);
	unsigned long fc;

	/* Pick the correct function code based on the key length */
	fc = (key_len == 16) ? CPACF_KM_AES_128 :
	     (key_len == 24) ? CPACF_KM_AES_192 :
	     (key_len == 32) ? CPACF_KM_AES_256 : 0;

	/* Check if the function code is available */
	sctx->fc = (fc && cpacf_test_func(&km_functions, fc)) ? fc : 0;
	if (!sctx->fc)
		return setkey_fallback_skcipher(tfm, in_key, key_len);

	sctx->key_len = key_len;
	memcpy(sctx->key, in_key, key_len);
	return 0;
}

static int ecb_aes_crypt(struct skcipher_request *req, unsigned long modifier)
{
	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
	struct s390_aes_ctx *sctx = crypto_skcipher_ctx(tfm);
	struct skcipher_walk walk;
	unsigned int nbytes, n;
	int ret;

	if (unlikely(!sctx->fc))
		return fallback_skcipher_crypt(sctx, req, modifier);

Annotation

Implementation Notes