Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 86aa9fc2 authored by Jan Glauber's avatar Jan Glauber Committed by Martin Schwidefsky
Browse files

[S390] move crypto options and some cleanup.



This patch moves the config options for the s390 crypto instructions
to the standard "Hardware crypto devices" menu. In addition some
cleanup has been done: use a flag for supported keylengths, add a
warning about machien limitation, return ENOTSUPP in case the
hardware has no support, remove superfluous printks and update
email addresses.

Signed-off-by: default avatarJan Glauber <jan.glauber@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 347d59d7
Loading
Loading
Loading
Loading
+60 −0
Original line number Diff line number Diff line
config CRYPTO_SHA1_S390
	tristate "SHA1 digest algorithm"
	depends on S390
	select CRYPTO_ALGAPI
	help
	  This is the s390 hardware accelerated implementation of the
	  SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).

config CRYPTO_SHA256_S390
	tristate "SHA256 digest algorithm"
	depends on S390
	select CRYPTO_ALGAPI
	help
	  This is the s390 hardware accelerated implementation of the
	  SHA256 secure hash standard (DFIPS 180-2).

	  This version of SHA implements a 256 bit hash with 128 bits of
	  security against collision attacks.

config CRYPTO_DES_S390
	tristate "DES and Triple DES cipher algorithms"
	depends on S390
	select CRYPTO_ALGAPI
	select CRYPTO_BLKCIPHER
	help
	  This us the s390 hardware accelerated implementation of the
	  DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3).

config CRYPTO_AES_S390
	tristate "AES cipher algorithms"
	depends on S390
	select CRYPTO_ALGAPI
	select CRYPTO_BLKCIPHER
	help
	  This is the s390 hardware accelerated implementation of the
	  AES cipher algorithms (FIPS-197). AES uses the Rijndael
	  algorithm.

	  Rijndael appears to be consistently a very good performer in
	  both hardware and software across a wide range of computing
	  environments regardless of its use in feedback or non-feedback
	  modes. Its key setup time is excellent, and its key agility is
	  good. Rijndael's very low memory requirements make it very well
	  suited for restricted-space environments, in which it also
	  demonstrates excellent performance. Rijndael's operations are
	  among the easiest to defend against power and timing attacks.

	  On s390 the System z9-109 currently only supports the key size
	  of 128 bit.

config S390_PRNG
	tristate "Pseudo random number generator device driver"
	depends on S390
	default "m"
	help
	  Select this option if you want to use the s390 pseudo random number
	  generator. The PRNG is part of the cryptograhic processor functions
	  and uses triple-DES to generate secure random numbers like the
	  ANSI X9.17 standard. The PRNG is usable via the char device
	  /dev/prandom.
+0 −2
Original line number Diff line number Diff line
@@ -6,5 +6,3 @@ obj-$(CONFIG_CRYPTO_SHA1_S390) += sha1_s390.o
obj-$(CONFIG_CRYPTO_SHA256_S390) += sha256_s390.o
obj-$(CONFIG_CRYPTO_DES_S390) += des_s390.o des_check_key.o
obj-$(CONFIG_CRYPTO_AES_S390) += aes_s390.o

obj-$(CONFIG_CRYPTO_TEST) += crypt_s390_query.o
+23 −24
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@
 * s390 implementation of the AES Cipher Algorithm.
 *
 * s390 Version:
 *   Copyright (C) 2005 IBM Deutschland GmbH, IBM Corporation
 *   Copyright IBM Corp. 2005,2007
 *   Author(s): Jan Glauber (jang@de.ibm.com)
 *
 * Derived from "crypto/aes.c"
@@ -27,9 +27,11 @@
/* data block size for all key lengths */
#define AES_BLOCK_SIZE		16

static int has_aes_128 = 0;
static int has_aes_192 = 0;
static int has_aes_256 = 0;
#define AES_KEYLEN_128		1
#define AES_KEYLEN_192		2
#define AES_KEYLEN_256		4

static char keylen_flag = 0;

struct s390_aes_ctx {
	u8 iv[AES_BLOCK_SIZE];
@@ -47,20 +49,19 @@ static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,

	switch (key_len) {
	case 16:
		if (!has_aes_128)
		if (!(keylen_flag & AES_KEYLEN_128))
			goto fail;
		break;
	case 24:
		if (!has_aes_192)
		if (!(keylen_flag & AES_KEYLEN_192))
			goto fail;

		break;
	case 32:
		if (!has_aes_256)
		if (!(keylen_flag & AES_KEYLEN_256))
			goto fail;
		break;
	default:
		/* invalid key length */
		goto fail;
		break;
	}
@@ -322,34 +323,32 @@ static int __init aes_init(void)
	int ret;

	if (crypt_s390_func_available(KM_AES_128_ENCRYPT))
		has_aes_128 = 1;
		keylen_flag |= AES_KEYLEN_128;
	if (crypt_s390_func_available(KM_AES_192_ENCRYPT))
		has_aes_192 = 1;
		keylen_flag |= AES_KEYLEN_192;
	if (crypt_s390_func_available(KM_AES_256_ENCRYPT))
		has_aes_256 = 1;
		keylen_flag |= AES_KEYLEN_256;

	if (!keylen_flag)
		return -EOPNOTSUPP;

	if (!has_aes_128 && !has_aes_192 && !has_aes_256)
		return -ENOSYS;
	/* z9 109 and z9 BC/EC only support 128 bit key length */
	if (keylen_flag == AES_KEYLEN_128)
		printk(KERN_INFO
		       "aes_s390: hardware acceleration only available for"
		       "128 bit keys\n");

	ret = crypto_register_alg(&aes_alg);
	if (ret != 0) {
		printk(KERN_INFO "crypt_s390: aes-s390 couldn't be loaded.\n");
	if (ret)
		goto aes_err;
	}

	ret = crypto_register_alg(&ecb_aes_alg);
	if (ret != 0) {
		printk(KERN_INFO
		       "crypt_s390: ecb-aes-s390 couldn't be loaded.\n");
	if (ret)
		goto ecb_aes_err;
	}

	ret = crypto_register_alg(&cbc_aes_alg);
	if (ret != 0) {
		printk(KERN_INFO
		       "crypt_s390: cbc-aes-s390 couldn't be loaded.\n");
	if (ret)
		goto cbc_aes_err;
	}

out:
	return ret;
+138 −142
Original line number Diff line number Diff line
@@ -3,8 +3,9 @@
 *
 * Support for s390 cryptographic instructions.
 *
 *   Copyright (C) 2003 IBM Deutschland GmbH, IBM Corporation
 *   Author(s): Thomas Spatzier (tspat@de.ibm.com)
 *   Copyright IBM Corp. 2003,2007
 *   Author(s): Thomas Spatzier
 *		Jan Glauber (jan.glauber@de.ibm.com)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
@@ -32,7 +33,8 @@ enum crypt_s390_operations {
	CRYPT_S390_KMAC = 0x0500
};

/* function codes for KM (CIPHER MESSAGE) instruction
/*
 * function codes for KM (CIPHER MESSAGE) instruction
 * 0x80 is the decipher modifier bit
 */
enum crypt_s390_km_func {
@@ -51,7 +53,8 @@ enum crypt_s390_km_func {
	KM_AES_256_DECRYPT  = CRYPT_S390_KM | 0x14 | 0x80,
};

/* function codes for KMC (CIPHER MESSAGE WITH CHAINING)
/*
 * function codes for KMC (CIPHER MESSAGE WITH CHAINING)
 * instruction
 */
enum crypt_s390_kmc_func {
@@ -70,7 +73,8 @@ enum crypt_s390_kmc_func {
	KMC_AES_256_DECRYPT  = CRYPT_S390_KMC | 0x14 | 0x80,
};

/* function codes for KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST)
/*
 * function codes for KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST)
 * instruction
 */
enum crypt_s390_kimd_func {
@@ -79,7 +83,8 @@ enum crypt_s390_kimd_func {
	KIMD_SHA_256 = CRYPT_S390_KIMD | 2,
};

/* function codes for KLMD (COMPUTE LAST MESSAGE DIGEST)
/*
 * function codes for KLMD (COMPUTE LAST MESSAGE DIGEST)
 * instruction
 */
enum crypt_s390_klmd_func {
@@ -88,7 +93,8 @@ enum crypt_s390_klmd_func {
	KLMD_SHA_256 = CRYPT_S390_KLMD | 2,
};

/* function codes for KMAC (COMPUTE MESSAGE AUTHENTICATION CODE)
/*
 * function codes for KMAC (COMPUTE MESSAGE AUTHENTICATION CODE)
 * instruction
 */
enum crypt_s390_kmac_func {
@@ -98,24 +104,21 @@ enum crypt_s390_kmac_func {
	KMAC_TDEA_192 = CRYPT_S390_KMAC | 3
};

/* status word for s390 crypto instructions' QUERY functions */
struct crypt_s390_query_status {
	u64 high;
	u64 low;
};

/*
/**
 * crypt_s390_km:
 * @func: the function code passed to KM; see crypt_s390_km_func
 * @param: address of parameter block; see POP for details on each func
 * @dest: address of destination memory area
 * @src: address of source memory area
 * @src_len: length of src operand in bytes
 *
 * Executes the KM (CIPHER MESSAGE) operation of the CPU.
 * @param func: the function code passed to KM; see crypt_s390_km_func
 * @param param: address of parameter block; see POP for details on each func
 * @param dest: address of destination memory area
 * @param src: address of source memory area
 * @param src_len: length of src operand in bytes
 * @returns < zero for failure, 0 for the query func, number of processed bytes
 * 	for encryption/decryption funcs
 *
 * Returns -1 for failure, 0 for the query func, number of processed
 * bytes for encryption/decryption funcs
 */
static inline int
crypt_s390_km(long func, void* param, u8* dest, const u8* src, long src_len)
static inline int crypt_s390_km(long func, void *param,
				u8 *dest, const u8 *src, long src_len)
{
	register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
	register void *__param asm("1") = param;
@@ -127,30 +130,31 @@ crypt_s390_km(long func, void* param, u8* dest, const u8* src, long src_len)
	asm volatile(
		"0:	.insn	rre,0xb92e0000,%3,%1 \n" /* KM opcode */
		"1:	brc	1,0b \n" /* handle partial completion */
		"	ahi	%0,%h7\n"
		"2:	ahi	%0,%h8\n"
		"3:\n"
		EX_TABLE(0b,3b) EX_TABLE(1b,2b)
		"	la	%0,0\n"
		"2:\n"
		EX_TABLE(0b,2b) EX_TABLE(1b,2b)
		: "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest)
		: "d" (__func), "a" (__param), "0" (-EFAULT),
		  "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
		: "d" (__func), "a" (__param), "0" (-1) : "cc", "memory");
	if (ret < 0)
		return ret;
	return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
}

/*
/**
 * crypt_s390_kmc:
 * @func: the function code passed to KM; see crypt_s390_kmc_func
 * @param: address of parameter block; see POP for details on each func
 * @dest: address of destination memory area
 * @src: address of source memory area
 * @src_len: length of src operand in bytes
 *
 * Executes the KMC (CIPHER MESSAGE WITH CHAINING) operation of the CPU.
 * @param func: the function code passed to KM; see crypt_s390_kmc_func
 * @param param: address of parameter block; see POP for details on each func
 * @param dest: address of destination memory area
 * @param src: address of source memory area
 * @param src_len: length of src operand in bytes
 * @returns < zero for failure, 0 for the query func, number of processed bytes
 * 	for encryption/decryption funcs
 *
 * Returns -1 for failure, 0 for the query func, number of processed
 * bytes for encryption/decryption funcs
 */
static inline int
crypt_s390_kmc(long func, void* param, u8* dest, const u8* src, long src_len)
static inline int crypt_s390_kmc(long func, void *param,
				 u8 *dest, const u8 *src, long src_len)
{
	register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
	register void *__param asm("1") = param;
@@ -162,30 +166,31 @@ crypt_s390_kmc(long func, void* param, u8* dest, const u8* src, long src_len)
	asm volatile(
		"0:	.insn	rre,0xb92f0000,%3,%1 \n" /* KMC opcode */
		"1:	brc	1,0b \n" /* handle partial completion */
		"	ahi	%0,%h7\n"
		"2:	ahi	%0,%h8\n"
		"3:\n"
		EX_TABLE(0b,3b) EX_TABLE(1b,2b)
		"	la	%0,0\n"
		"2:\n"
		EX_TABLE(0b,2b) EX_TABLE(1b,2b)
		: "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest)
		: "d" (__func), "a" (__param), "0" (-EFAULT),
		  "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
		: "d" (__func), "a" (__param), "0" (-1) : "cc", "memory");
	if (ret < 0)
		return ret;
	return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
}

/*
/**
 * crypt_s390_kimd:
 * @func: the function code passed to KM; see crypt_s390_kimd_func
 * @param: address of parameter block; see POP for details on each func
 * @src: address of source memory area
 * @src_len: length of src operand in bytes
 *
 * Executes the KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) operation
 * of the CPU.
 * @param func: the function code passed to KM; see crypt_s390_kimd_func
 * @param param: address of parameter block; see POP for details on each func
 * @param src: address of source memory area
 * @param src_len: length of src operand in bytes
 * @returns < zero for failure, 0 for the query func, number of processed bytes
 * 	for digest funcs
 *
 * Returns -1 for failure, 0 for the query func, number of processed
 * bytes for digest funcs
 */
static inline int
crypt_s390_kimd(long func, void* param, const u8* src, long src_len)
static inline int crypt_s390_kimd(long func, void *param,
				  const u8 *src, long src_len)
{
	register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
	register void *__param asm("1") = param;
@@ -196,29 +201,30 @@ crypt_s390_kimd(long func, void* param, const u8* src, long src_len)
	asm volatile(
		"0:	.insn	rre,0xb93e0000,%1,%1 \n" /* KIMD opcode */
		"1:	brc	1,0b \n" /* handle partial completion */
		"	ahi	%0,%h6\n"
		"2:	ahi	%0,%h7\n"
		"3:\n"
		EX_TABLE(0b,3b) EX_TABLE(1b,2b)
		"	la	%0,0\n"
		"2:\n"
		EX_TABLE(0b,2b) EX_TABLE(1b,2b)
		: "=d" (ret), "+a" (__src), "+d" (__src_len)
		: "d" (__func), "a" (__param), "0" (-EFAULT),
		  "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
		: "d" (__func), "a" (__param), "0" (-1) : "cc", "memory");
	if (ret < 0)
		return ret;
	return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
}

/*
/**
 * crypt_s390_klmd:
 * @func: the function code passed to KM; see crypt_s390_klmd_func
 * @param: address of parameter block; see POP for details on each func
 * @src: address of source memory area
 * @src_len: length of src operand in bytes
 *
 * Executes the KLMD (COMPUTE LAST MESSAGE DIGEST) operation of the CPU.
 * @param func: the function code passed to KM; see crypt_s390_klmd_func
 * @param param: address of parameter block; see POP for details on each func
 * @param src: address of source memory area
 * @param src_len: length of src operand in bytes
 * @returns < zero for failure, 0 for the query func, number of processed bytes
 * 	for digest funcs
 *
 * Returns -1 for failure, 0 for the query func, number of processed
 * bytes for digest funcs
 */
static inline int
crypt_s390_klmd(long func, void* param, const u8* src, long src_len)
static inline int crypt_s390_klmd(long func, void *param,
				  const u8 *src, long src_len)
{
	register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
	register void *__param asm("1") = param;
@@ -229,30 +235,31 @@ crypt_s390_klmd(long func, void* param, const u8* src, long src_len)
	asm volatile(
		"0:	.insn	rre,0xb93f0000,%1,%1 \n" /* KLMD opcode */
		"1:	brc	1,0b \n" /* handle partial completion */
		"	ahi	%0,%h6\n"
		"2:	ahi	%0,%h7\n"
		"3:\n"
		EX_TABLE(0b,3b) EX_TABLE(1b,2b)
		"	la	%0,0\n"
		"2:\n"
		EX_TABLE(0b,2b) EX_TABLE(1b,2b)
		: "=d" (ret), "+a" (__src), "+d" (__src_len)
		: "d" (__func), "a" (__param), "0" (-EFAULT),
		  "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
		: "d" (__func), "a" (__param), "0" (-1) : "cc", "memory");
	if (ret < 0)
		return ret;
	return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
}

/*
/**
 * crypt_s390_kmac:
 * @func: the function code passed to KM; see crypt_s390_klmd_func
 * @param: address of parameter block; see POP for details on each func
 * @src: address of source memory area
 * @src_len: length of src operand in bytes
 *
 * Executes the KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) operation
 * of the CPU.
 * @param func: the function code passed to KM; see crypt_s390_klmd_func
 * @param param: address of parameter block; see POP for details on each func
 * @param src: address of source memory area
 * @param src_len: length of src operand in bytes
 * @returns < zero for failure, 0 for the query func, number of processed bytes
 * 	for digest funcs
 *
 * Returns -1 for failure, 0 for the query func, number of processed
 * bytes for digest funcs
 */
static inline int
crypt_s390_kmac(long func, void* param, const u8* src, long src_len)
static inline int crypt_s390_kmac(long func, void *param,
				  const u8 *src, long src_len)
{
	register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
	register void *__param asm("1") = param;
@@ -263,32 +270,29 @@ crypt_s390_kmac(long func, void* param, const u8* src, long src_len)
	asm volatile(
		"0:	.insn	rre,0xb91e0000,%1,%1 \n" /* KLAC opcode */
		"1:	brc	1,0b \n" /* handle partial completion */
		"	ahi	%0,%h6\n"
		"2:	ahi	%0,%h7\n"
		"3:\n"
		EX_TABLE(0b,3b) EX_TABLE(1b,2b)
		"	la	%0,0\n"
		"2:\n"
		EX_TABLE(0b,2b) EX_TABLE(1b,2b)
		: "=d" (ret), "+a" (__src), "+d" (__src_len)
		: "d" (__func), "a" (__param), "0" (-EFAULT),
		  "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
		: "d" (__func), "a" (__param), "0" (-1) : "cc", "memory");
	if (ret < 0)
		return ret;
	return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
}

/**
 * crypt_s390_func_available:
 * @func: the function code of the specific function; 0 if op in general
 *
 * Tests if a specific crypto function is implemented on the machine.
 * @param func:	the function code of the specific function; 0 if op in general
 * @return	1 if func available; 0 if func or op in general not available
 *
 * Returns 1 if func available; 0 if func or op in general not available
 */
static inline int
crypt_s390_func_available(int func)
static inline int crypt_s390_func_available(int func)
{
	unsigned char status[16];
	int ret;

	struct crypt_s390_query_status status = {
		.high = 0,
		.low = 0
	};
	switch (func & CRYPT_S390_OP_MASK) {
	case CRYPT_S390_KM:
		ret = crypt_s390_km(KM_QUERY, &status, NULL, NULL, 0);
@@ -306,21 +310,13 @@ crypt_s390_func_available(int func)
		ret = crypt_s390_kmac(KMAC_QUERY, &status, NULL, 0);
		break;
	default:
			ret = 0;
			return ret;
		return 0;
	}
	if (ret >= 0){
	if (ret < 0)
		return 0;
	func &= CRYPT_S390_FUNC_MASK;
		func &= 0x7f; //mask modifier bit
		if (func < 64){
			ret = (status.high >> (64 - func - 1)) & 0x1;
		} else {
			ret = (status.low >> (128 - func - 1)) & 0x1;
		}
	} else {
		ret = 0;
	}
	return ret;
	func &= 0x7f;		/* mask modifier bit */
	return (status[func >> 3] & (0x80 >> (func & 7))) != 0;
}

#endif // _CRYPTO_ARCH_S390_CRYPT_S390_H
#endif	/* _CRYPTO_ARCH_S390_CRYPT_S390_H */
+0 −129
Original line number Diff line number Diff line
/*
 * Cryptographic API.
 *
 * Support for s390 cryptographic instructions.
 * Testing module for querying processor crypto capabilities.
 *
 * Copyright (c) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
 * Author(s): Thomas Spatzier (tspat@de.ibm.com)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 */
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <asm/errno.h>
#include "crypt_s390.h"

static void query_available_functions(void)
{
	printk(KERN_INFO "#####################\n");

	/* query available KM functions */
	printk(KERN_INFO "KM_QUERY: %d\n",
		crypt_s390_func_available(KM_QUERY));
	printk(KERN_INFO "KM_DEA: %d\n",
		crypt_s390_func_available(KM_DEA_ENCRYPT));
	printk(KERN_INFO "KM_TDEA_128: %d\n",
		crypt_s390_func_available(KM_TDEA_128_ENCRYPT));
	printk(KERN_INFO "KM_TDEA_192: %d\n",
		crypt_s390_func_available(KM_TDEA_192_ENCRYPT));
	printk(KERN_INFO "KM_AES_128: %d\n",
		crypt_s390_func_available(KM_AES_128_ENCRYPT));
	printk(KERN_INFO "KM_AES_192: %d\n",
		crypt_s390_func_available(KM_AES_192_ENCRYPT));
	printk(KERN_INFO "KM_AES_256: %d\n",
		crypt_s390_func_available(KM_AES_256_ENCRYPT));

	/* query available KMC functions */
	printk(KERN_INFO "KMC_QUERY: %d\n",
		crypt_s390_func_available(KMC_QUERY));
	printk(KERN_INFO "KMC_DEA: %d\n",
		crypt_s390_func_available(KMC_DEA_ENCRYPT));
	printk(KERN_INFO "KMC_TDEA_128: %d\n",
		crypt_s390_func_available(KMC_TDEA_128_ENCRYPT));
	printk(KERN_INFO "KMC_TDEA_192: %d\n",
		crypt_s390_func_available(KMC_TDEA_192_ENCRYPT));
	printk(KERN_INFO "KMC_AES_128: %d\n",
		crypt_s390_func_available(KMC_AES_128_ENCRYPT));
	printk(KERN_INFO "KMC_AES_192: %d\n",
		crypt_s390_func_available(KMC_AES_192_ENCRYPT));
	printk(KERN_INFO "KMC_AES_256: %d\n",
		crypt_s390_func_available(KMC_AES_256_ENCRYPT));

	/* query available KIMD functions */
	printk(KERN_INFO "KIMD_QUERY: %d\n",
		crypt_s390_func_available(KIMD_QUERY));
	printk(KERN_INFO "KIMD_SHA_1: %d\n",
		crypt_s390_func_available(KIMD_SHA_1));
	printk(KERN_INFO "KIMD_SHA_256: %d\n",
		crypt_s390_func_available(KIMD_SHA_256));

	/* query available KLMD functions */
	printk(KERN_INFO "KLMD_QUERY: %d\n",
		crypt_s390_func_available(KLMD_QUERY));
	printk(KERN_INFO "KLMD_SHA_1: %d\n",
		crypt_s390_func_available(KLMD_SHA_1));
	printk(KERN_INFO "KLMD_SHA_256: %d\n",
		crypt_s390_func_available(KLMD_SHA_256));

	/* query available KMAC functions */
	printk(KERN_INFO "KMAC_QUERY: %d\n",
		crypt_s390_func_available(KMAC_QUERY));
	printk(KERN_INFO "KMAC_DEA: %d\n",
		crypt_s390_func_available(KMAC_DEA));
	printk(KERN_INFO "KMAC_TDEA_128: %d\n",
		crypt_s390_func_available(KMAC_TDEA_128));
	printk(KERN_INFO "KMAC_TDEA_192: %d\n",
		crypt_s390_func_available(KMAC_TDEA_192));
}

static int init(void)
{
	struct crypt_s390_query_status status = {
		.high = 0,
		.low = 0
	};

	printk(KERN_INFO "crypt_s390: querying available crypto functions\n");
	crypt_s390_km(KM_QUERY, &status, NULL, NULL, 0);
	printk(KERN_INFO "KM:\t%016llx %016llx\n",
			(unsigned long long) status.high,
			(unsigned long long) status.low);
	status.high = status.low = 0;
	crypt_s390_kmc(KMC_QUERY, &status, NULL, NULL, 0);
	printk(KERN_INFO "KMC:\t%016llx %016llx\n",
			(unsigned long long) status.high,
			(unsigned long long) status.low);
	status.high = status.low = 0;
	crypt_s390_kimd(KIMD_QUERY, &status, NULL, 0);
	printk(KERN_INFO "KIMD:\t%016llx %016llx\n",
			(unsigned long long) status.high,
			(unsigned long long) status.low);
	status.high = status.low = 0;
	crypt_s390_klmd(KLMD_QUERY, &status, NULL, 0);
	printk(KERN_INFO "KLMD:\t%016llx %016llx\n",
			(unsigned long long) status.high,
			(unsigned long long) status.low);
	status.high = status.low = 0;
	crypt_s390_kmac(KMAC_QUERY, &status, NULL, 0);
	printk(KERN_INFO "KMAC:\t%016llx %016llx\n",
			(unsigned long long) status.high,
			(unsigned long long) status.low);

	query_available_functions();
	return -ECANCELED;
}

static void __exit cleanup(void)
{
}

module_init(init);
module_exit(cleanup);

MODULE_LICENSE("GPL");
Loading