aboutsummaryrefslogtreecommitdiff
path: root/arch/s390/crypto/sha256_s390.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/crypto/sha256_s390.c')
-rw-r--r--arch/s390/crypto/sha256_s390.c206
1 files changed, 102 insertions, 104 deletions
diff --git a/arch/s390/crypto/sha256_s390.c b/arch/s390/crypto/sha256_s390.c
index b75bdbd476c..9b853809a49 100644
--- a/arch/s390/crypto/sha256_s390.c
+++ b/arch/s390/crypto/sha256_s390.c
@@ -1,151 +1,149 @@
/*
* Cryptographic API.
*
- * s390 implementation of the SHA256 Secure Hash Algorithm.
+ * s390 implementation of the SHA256 and SHA224 Secure Hash Algorithm.
*
* s390 Version:
- * Copyright (C) 2005 IBM Deutschland GmbH, IBM Corporation
+ * Copyright IBM Corp. 2005, 2011
* Author(s): Jan Glauber (jang@de.ibm.com)
*
- * Derived from "crypto/sha256.c"
- * and "arch/s390/crypto/sha1_s390.c"
- *
* 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 <crypto/internal/hash.h>
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/crypto.h>
+#include <crypto/sha.h>
#include "crypt_s390.h"
+#include "sha.h"
-#define SHA256_DIGEST_SIZE 32
-#define SHA256_BLOCK_SIZE 64
-
-struct s390_sha256_ctx {
- u64 count;
- u32 state[8];
- u8 buf[2 * SHA256_BLOCK_SIZE];
-};
-
-static void sha256_init(void *ctx)
+static int sha256_init(struct shash_desc *desc)
{
- struct s390_sha256_ctx *sctx = ctx;
-
- sctx->state[0] = 0x6a09e667;
- sctx->state[1] = 0xbb67ae85;
- sctx->state[2] = 0x3c6ef372;
- sctx->state[3] = 0xa54ff53a;
- sctx->state[4] = 0x510e527f;
- sctx->state[5] = 0x9b05688c;
- sctx->state[6] = 0x1f83d9ab;
- sctx->state[7] = 0x5be0cd19;
+ struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
+
+ sctx->state[0] = SHA256_H0;
+ sctx->state[1] = SHA256_H1;
+ sctx->state[2] = SHA256_H2;
+ sctx->state[3] = SHA256_H3;
+ sctx->state[4] = SHA256_H4;
+ sctx->state[5] = SHA256_H5;
+ sctx->state[6] = SHA256_H6;
+ sctx->state[7] = SHA256_H7;
sctx->count = 0;
- memset(sctx->buf, 0, sizeof(sctx->buf));
-}
+ sctx->func = KIMD_SHA_256;
-static void sha256_update(void *ctx, const u8 *data, unsigned int len)
-{
- struct s390_sha256_ctx *sctx = ctx;
- unsigned int index;
-
- /* how much is already in the buffer? */
- index = sctx->count / 8 & 0x3f;
-
- /* update message bit length */
- sctx->count += len * 8;
-
- /* process one block */
- if ((index + len) >= SHA256_BLOCK_SIZE) {
- memcpy(sctx->buf + index, data, SHA256_BLOCK_SIZE - index);
- crypt_s390_kimd(KIMD_SHA_256, sctx->state, sctx->buf,
- SHA256_BLOCK_SIZE);
- data += SHA256_BLOCK_SIZE - index;
- len -= SHA256_BLOCK_SIZE - index;
- }
-
- /* anything left? */
- if (len)
- memcpy(sctx->buf + index , data, len);
+ return 0;
}
-static void pad_message(struct s390_sha256_ctx* sctx)
+static int sha256_export(struct shash_desc *desc, void *out)
{
- int index, end;
-
- index = sctx->count / 8 & 0x3f;
- end = index < 56 ? SHA256_BLOCK_SIZE : 2 * SHA256_BLOCK_SIZE;
-
- /* start pad with 1 */
- sctx->buf[index] = 0x80;
-
- /* pad with zeros */
- index++;
- memset(sctx->buf + index, 0x00, end - index - 8);
+ struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
+ struct sha256_state *octx = out;
- /* append message length */
- memcpy(sctx->buf + end - 8, &sctx->count, sizeof sctx->count);
-
- sctx->count = end * 8;
+ octx->count = sctx->count;
+ memcpy(octx->state, sctx->state, sizeof(octx->state));
+ memcpy(octx->buf, sctx->buf, sizeof(octx->buf));
+ return 0;
}
-/* Add padding and return the message digest */
-static void sha256_final(void* ctx, u8 *out)
+static int sha256_import(struct shash_desc *desc, const void *in)
{
- struct s390_sha256_ctx *sctx = ctx;
-
- /* must perform manual padding */
- pad_message(sctx);
+ struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
+ const struct sha256_state *ictx = in;
+
+ sctx->count = ictx->count;
+ memcpy(sctx->state, ictx->state, sizeof(ictx->state));
+ memcpy(sctx->buf, ictx->buf, sizeof(ictx->buf));
+ sctx->func = KIMD_SHA_256;
+ return 0;
+}
- crypt_s390_kimd(KIMD_SHA_256, sctx->state, sctx->buf,
- sctx->count / 8);
+static struct shash_alg sha256_alg = {
+ .digestsize = SHA256_DIGEST_SIZE,
+ .init = sha256_init,
+ .update = s390_sha_update,
+ .final = s390_sha_final,
+ .export = sha256_export,
+ .import = sha256_import,
+ .descsize = sizeof(struct s390_sha_ctx),
+ .statesize = sizeof(struct sha256_state),
+ .base = {
+ .cra_name = "sha256",
+ .cra_driver_name= "sha256-s390",
+ .cra_priority = CRYPT_S390_PRIORITY,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA256_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+};
- /* copy digest to out */
- memcpy(out, sctx->state, SHA256_DIGEST_SIZE);
+static int sha224_init(struct shash_desc *desc)
+{
+ struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
+
+ sctx->state[0] = SHA224_H0;
+ sctx->state[1] = SHA224_H1;
+ sctx->state[2] = SHA224_H2;
+ sctx->state[3] = SHA224_H3;
+ sctx->state[4] = SHA224_H4;
+ sctx->state[5] = SHA224_H5;
+ sctx->state[6] = SHA224_H6;
+ sctx->state[7] = SHA224_H7;
+ sctx->count = 0;
+ sctx->func = KIMD_SHA_256;
- /* wipe context */
- memset(sctx, 0, sizeof *sctx);
+ return 0;
}
-static struct crypto_alg alg = {
- .cra_name = "sha256",
- .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
- .cra_blocksize = SHA256_BLOCK_SIZE,
- .cra_ctxsize = sizeof(struct s390_sha256_ctx),
- .cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(alg.cra_list),
- .cra_u = { .digest = {
- .dia_digestsize = SHA256_DIGEST_SIZE,
- .dia_init = sha256_init,
- .dia_update = sha256_update,
- .dia_final = sha256_final } }
+static struct shash_alg sha224_alg = {
+ .digestsize = SHA224_DIGEST_SIZE,
+ .init = sha224_init,
+ .update = s390_sha_update,
+ .final = s390_sha_final,
+ .export = sha256_export,
+ .import = sha256_import,
+ .descsize = sizeof(struct s390_sha_ctx),
+ .statesize = sizeof(struct sha256_state),
+ .base = {
+ .cra_name = "sha224",
+ .cra_driver_name= "sha224-s390",
+ .cra_priority = CRYPT_S390_PRIORITY,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA224_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
};
-static int init(void)
+static int __init sha256_s390_init(void)
{
int ret;
- if (!crypt_s390_func_available(KIMD_SHA_256))
- return -ENOSYS;
-
- ret = crypto_register_alg(&alg);
- if (ret != 0)
- printk(KERN_INFO "crypt_s390: sha256_s390 couldn't be loaded.");
+ if (!crypt_s390_func_available(KIMD_SHA_256, CRYPT_S390_MSA))
+ return -EOPNOTSUPP;
+ ret = crypto_register_shash(&sha256_alg);
+ if (ret < 0)
+ goto out;
+ ret = crypto_register_shash(&sha224_alg);
+ if (ret < 0)
+ crypto_unregister_shash(&sha256_alg);
+out:
return ret;
}
-static void __exit fini(void)
+static void __exit sha256_s390_fini(void)
{
- crypto_unregister_alg(&alg);
+ crypto_unregister_shash(&sha224_alg);
+ crypto_unregister_shash(&sha256_alg);
}
-module_init(init);
-module_exit(fini);
+module_init(sha256_s390_init);
+module_exit(sha256_s390_fini);
MODULE_ALIAS("sha256");
-
+MODULE_ALIAS("sha224");
MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("SHA256 Secure Hash Algorithm");
+MODULE_DESCRIPTION("SHA256 and SHA224 Secure Hash Algorithm");