OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [arch/] [s390/] [crypto/] [sha1_s390.c] - Blame information for rev 86

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 63 marcus.erl
/*
2
 * Cryptographic API.
3
 *
4
 * s390 implementation of the SHA1 Secure Hash Algorithm.
5
 *
6
 * Derived from cryptoapi implementation, adapted for in-place
7
 * scatterlist interface.  Originally based on the public domain
8
 * implementation written by Steve Reid.
9
 *
10
 * s390 Version:
11
 *   Copyright IBM Corp. 2003,2007
12
 *   Author(s): Thomas Spatzier
13
 *              Jan Glauber (jan.glauber@de.ibm.com)
14
 *
15
 * Derived from "crypto/sha1_generic.c"
16
 *   Copyright (c) Alan Smithee.
17
 *   Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
18
 *   Copyright (c) Jean-Francois Dive <jef@linuxbe.org>
19
 *
20
 * This program is free software; you can redistribute it and/or modify it
21
 * under the terms of the GNU General Public License as published by the Free
22
 * Software Foundation; either version 2 of the License, or (at your option)
23
 * any later version.
24
 *
25
 */
26
#include <linux/init.h>
27
#include <linux/module.h>
28
#include <linux/crypto.h>
29
#include <crypto/sha.h>
30
 
31
#include "crypt_s390.h"
32
 
33
struct s390_sha1_ctx {
34
        u64 count;              /* message length */
35
        u32 state[5];
36
        u8 buf[2 * SHA1_BLOCK_SIZE];
37
};
38
 
39
static void sha1_init(struct crypto_tfm *tfm)
40
{
41
        struct s390_sha1_ctx *sctx = crypto_tfm_ctx(tfm);
42
 
43
        sctx->state[0] = SHA1_H0;
44
        sctx->state[1] = SHA1_H1;
45
        sctx->state[2] = SHA1_H2;
46
        sctx->state[3] = SHA1_H3;
47
        sctx->state[4] = SHA1_H4;
48
        sctx->count = 0;
49
}
50
 
51
static void sha1_update(struct crypto_tfm *tfm, const u8 *data,
52
                        unsigned int len)
53
{
54
        struct s390_sha1_ctx *sctx = crypto_tfm_ctx(tfm);
55
        unsigned int index;
56
        int ret;
57
 
58
        /* how much is already in the buffer? */
59
        index = sctx->count & 0x3f;
60
 
61
        sctx->count += len;
62
 
63
        if (index + len < SHA1_BLOCK_SIZE)
64
                goto store;
65
 
66
        /* process one stored block */
67
        if (index) {
68
                memcpy(sctx->buf + index, data, SHA1_BLOCK_SIZE - index);
69
                ret = crypt_s390_kimd(KIMD_SHA_1, sctx->state, sctx->buf,
70
                                      SHA1_BLOCK_SIZE);
71
                BUG_ON(ret != SHA1_BLOCK_SIZE);
72
                data += SHA1_BLOCK_SIZE - index;
73
                len -= SHA1_BLOCK_SIZE - index;
74
        }
75
 
76
        /* process as many blocks as possible */
77
        if (len >= SHA1_BLOCK_SIZE) {
78
                ret = crypt_s390_kimd(KIMD_SHA_1, sctx->state, data,
79
                                      len & ~(SHA1_BLOCK_SIZE - 1));
80
                BUG_ON(ret != (len & ~(SHA1_BLOCK_SIZE - 1)));
81
                data += ret;
82
                len -= ret;
83
        }
84
 
85
store:
86
        /* anything left? */
87
        if (len)
88
                memcpy(sctx->buf + index , data, len);
89
}
90
 
91
/* Add padding and return the message digest. */
92
static void sha1_final(struct crypto_tfm *tfm, u8 *out)
93
{
94
        struct s390_sha1_ctx *sctx = crypto_tfm_ctx(tfm);
95
        u64 bits;
96
        unsigned int index, end;
97
        int ret;
98
 
99
        /* must perform manual padding */
100
        index = sctx->count & 0x3f;
101
        end =  (index < 56) ? SHA1_BLOCK_SIZE : (2 * SHA1_BLOCK_SIZE);
102
 
103
        /* start pad with 1 */
104
        sctx->buf[index] = 0x80;
105
 
106
        /* pad with zeros */
107
        index++;
108
        memset(sctx->buf + index, 0x00, end - index - 8);
109
 
110
        /* append message length */
111
        bits = sctx->count * 8;
112
        memcpy(sctx->buf + end - 8, &bits, sizeof(bits));
113
 
114
        ret = crypt_s390_kimd(KIMD_SHA_1, sctx->state, sctx->buf, end);
115
        BUG_ON(ret != end);
116
 
117
        /* copy digest to out */
118
        memcpy(out, sctx->state, SHA1_DIGEST_SIZE);
119
 
120
        /* wipe context */
121
        memset(sctx, 0, sizeof *sctx);
122
}
123
 
124
static struct crypto_alg alg = {
125
        .cra_name       =       "sha1",
126
        .cra_driver_name=       "sha1-s390",
127
        .cra_priority   =       CRYPT_S390_PRIORITY,
128
        .cra_flags      =       CRYPTO_ALG_TYPE_DIGEST,
129
        .cra_blocksize  =       SHA1_BLOCK_SIZE,
130
        .cra_ctxsize    =       sizeof(struct s390_sha1_ctx),
131
        .cra_module     =       THIS_MODULE,
132
        .cra_list       =       LIST_HEAD_INIT(alg.cra_list),
133
        .cra_u          =       { .digest = {
134
        .dia_digestsize =       SHA1_DIGEST_SIZE,
135
        .dia_init       =       sha1_init,
136
        .dia_update     =       sha1_update,
137
        .dia_final      =       sha1_final } }
138
};
139
 
140
static int __init init(void)
141
{
142
        if (!crypt_s390_func_available(KIMD_SHA_1))
143
                return -EOPNOTSUPP;
144
 
145
        return crypto_register_alg(&alg);
146
}
147
 
148
static void __exit fini(void)
149
{
150
        crypto_unregister_alg(&alg);
151
}
152
 
153
module_init(init);
154
module_exit(fini);
155
 
156
MODULE_ALIAS("sha1");
157
 
158
MODULE_LICENSE("GPL");
159
MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm");

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.