aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/cavium-octeon
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-02-14 12:47:01 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-14 12:47:01 -0500
commitfee5429e028c414d80d036198db30454cfd91b7a (patch)
tree485f37a974e4ab85339021c794d1782e2d761c5b /arch/mips/cavium-octeon
parent83e047c104aa95a8a683d6bd421df1551c17dbd2 (diff)
parent96692a7305c49845e3cbf5a60cfcb207c5dc4030 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Pull crypto update from Herbert Xu: "Here is the crypto update for 3.20: - Added 192/256-bit key support to aesni GCM. - Added MIPS OCTEON MD5 support. - Fixed hwrng starvation and race conditions. - Added note that memzero_explicit is not a subsitute for memset. - Added user-space interface for crypto_rng. - Misc fixes" * git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (71 commits) crypto: tcrypt - do not allocate iv on stack for aead speed tests crypto: testmgr - limit IV copy length in aead tests crypto: tcrypt - fix buflen reminder calculation crypto: testmgr - mark rfc4106(gcm(aes)) as fips_allowed crypto: caam - fix resource clean-up on error path for caam_jr_init crypto: caam - pair irq map and dispose in the same function crypto: ccp - terminate ccp_support array with empty element crypto: caam - remove unused local variable crypto: caam - remove dead code crypto: caam - don't emit ICV check failures to dmesg hwrng: virtio - drop extra empty line crypto: replace scatterwalk_sg_next with sg_next crypto: atmel - Free memory in error path crypto: doc - remove colons in comments crypto: seqiv - Ensure that IV size is at least 8 bytes crypto: cts - Weed out non-CBC algorithms MAINTAINERS: add linux-crypto to hw random crypto: cts - Remove bogus use of seqiv crypto: qat - don't need qat_auth_state struct crypto: algif_rng - fix sparse non static symbol warning ...
Diffstat (limited to 'arch/mips/cavium-octeon')
-rw-r--r--arch/mips/cavium-octeon/Makefile1
-rw-r--r--arch/mips/cavium-octeon/crypto/Makefile7
-rw-r--r--arch/mips/cavium-octeon/crypto/octeon-crypto.c66
-rw-r--r--arch/mips/cavium-octeon/crypto/octeon-crypto.h75
-rw-r--r--arch/mips/cavium-octeon/crypto/octeon-md5.c216
-rw-r--r--arch/mips/cavium-octeon/executive/octeon-model.c6
6 files changed, 371 insertions, 0 deletions
diff --git a/arch/mips/cavium-octeon/Makefile b/arch/mips/cavium-octeon/Makefile
index 42f5f1a4b40a..69a8a8dabc2b 100644
--- a/arch/mips/cavium-octeon/Makefile
+++ b/arch/mips/cavium-octeon/Makefile
@@ -16,6 +16,7 @@ obj-y := cpu.o setup.o octeon-platform.o octeon-irq.o csrc-octeon.o
16obj-y += dma-octeon.o 16obj-y += dma-octeon.o
17obj-y += octeon-memcpy.o 17obj-y += octeon-memcpy.o
18obj-y += executive/ 18obj-y += executive/
19obj-y += crypto/
19 20
20obj-$(CONFIG_MTD) += flash_setup.o 21obj-$(CONFIG_MTD) += flash_setup.o
21obj-$(CONFIG_SMP) += smp.o 22obj-$(CONFIG_SMP) += smp.o
diff --git a/arch/mips/cavium-octeon/crypto/Makefile b/arch/mips/cavium-octeon/crypto/Makefile
new file mode 100644
index 000000000000..a74f76d85a2f
--- /dev/null
+++ b/arch/mips/cavium-octeon/crypto/Makefile
@@ -0,0 +1,7 @@
1#
2# OCTEON-specific crypto modules.
3#
4
5obj-y += octeon-crypto.o
6
7obj-$(CONFIG_CRYPTO_MD5_OCTEON) += octeon-md5.o
diff --git a/arch/mips/cavium-octeon/crypto/octeon-crypto.c b/arch/mips/cavium-octeon/crypto/octeon-crypto.c
new file mode 100644
index 000000000000..7c82ff463b65
--- /dev/null
+++ b/arch/mips/cavium-octeon/crypto/octeon-crypto.c
@@ -0,0 +1,66 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2004-2012 Cavium Networks
7 */
8
9#include <asm/cop2.h>
10#include <linux/module.h>
11#include <linux/interrupt.h>
12
13#include "octeon-crypto.h"
14
15/**
16 * Enable access to Octeon's COP2 crypto hardware for kernel use. Wrap any
17 * crypto operations in calls to octeon_crypto_enable/disable in order to make
18 * sure the state of COP2 isn't corrupted if userspace is also performing
19 * hardware crypto operations. Allocate the state parameter on the stack.
20 * Preemption must be disabled to prevent context switches.
21 *
22 * @state: Pointer to state structure to store current COP2 state in.
23 *
24 * Returns: Flags to be passed to octeon_crypto_disable()
25 */
26unsigned long octeon_crypto_enable(struct octeon_cop2_state *state)
27{
28 int status;
29 unsigned long flags;
30
31 local_irq_save(flags);
32 status = read_c0_status();
33 write_c0_status(status | ST0_CU2);
34 if (KSTK_STATUS(current) & ST0_CU2) {
35 octeon_cop2_save(&(current->thread.cp2));
36 KSTK_STATUS(current) &= ~ST0_CU2;
37 status &= ~ST0_CU2;
38 } else if (status & ST0_CU2) {
39 octeon_cop2_save(state);
40 }
41 local_irq_restore(flags);
42 return status & ST0_CU2;
43}
44EXPORT_SYMBOL_GPL(octeon_crypto_enable);
45
46/**
47 * Disable access to Octeon's COP2 crypto hardware in the kernel. This must be
48 * called after an octeon_crypto_enable() before any context switch or return to
49 * userspace.
50 *
51 * @state: Pointer to COP2 state to restore
52 * @flags: Return value from octeon_crypto_enable()
53 */
54void octeon_crypto_disable(struct octeon_cop2_state *state,
55 unsigned long crypto_flags)
56{
57 unsigned long flags;
58
59 local_irq_save(flags);
60 if (crypto_flags & ST0_CU2)
61 octeon_cop2_restore(state);
62 else
63 write_c0_status(read_c0_status() & ~ST0_CU2);
64 local_irq_restore(flags);
65}
66EXPORT_SYMBOL_GPL(octeon_crypto_disable);
diff --git a/arch/mips/cavium-octeon/crypto/octeon-crypto.h b/arch/mips/cavium-octeon/crypto/octeon-crypto.h
new file mode 100644
index 000000000000..e2a4aece9c24
--- /dev/null
+++ b/arch/mips/cavium-octeon/crypto/octeon-crypto.h
@@ -0,0 +1,75 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2012-2013 Cavium Inc., All Rights Reserved.
7 *
8 * MD5 instruction definitions added by Aaro Koskinen <aaro.koskinen@iki.fi>.
9 *
10 */
11#ifndef __LINUX_OCTEON_CRYPTO_H
12#define __LINUX_OCTEON_CRYPTO_H
13
14#include <linux/sched.h>
15#include <asm/mipsregs.h>
16
17#define OCTEON_CR_OPCODE_PRIORITY 300
18
19extern unsigned long octeon_crypto_enable(struct octeon_cop2_state *state);
20extern void octeon_crypto_disable(struct octeon_cop2_state *state,
21 unsigned long flags);
22
23/*
24 * Macros needed to implement MD5:
25 */
26
27/*
28 * The index can be 0-1.
29 */
30#define write_octeon_64bit_hash_dword(value, index) \
31do { \
32 __asm__ __volatile__ ( \
33 "dmtc2 %[rt],0x0048+" STR(index) \
34 : \
35 : [rt] "d" (value)); \
36} while (0)
37
38/*
39 * The index can be 0-1.
40 */
41#define read_octeon_64bit_hash_dword(index) \
42({ \
43 u64 __value; \
44 \
45 __asm__ __volatile__ ( \
46 "dmfc2 %[rt],0x0048+" STR(index) \
47 : [rt] "=d" (__value) \
48 : ); \
49 \
50 __value; \
51})
52
53/*
54 * The index can be 0-6.
55 */
56#define write_octeon_64bit_block_dword(value, index) \
57do { \
58 __asm__ __volatile__ ( \
59 "dmtc2 %[rt],0x0040+" STR(index) \
60 : \
61 : [rt] "d" (value)); \
62} while (0)
63
64/*
65 * The value is the final block dword (64-bit).
66 */
67#define octeon_md5_start(value) \
68do { \
69 __asm__ __volatile__ ( \
70 "dmtc2 %[rt],0x4047" \
71 : \
72 : [rt] "d" (value)); \
73} while (0)
74
75#endif /* __LINUX_OCTEON_CRYPTO_H */
diff --git a/arch/mips/cavium-octeon/crypto/octeon-md5.c b/arch/mips/cavium-octeon/crypto/octeon-md5.c
new file mode 100644
index 000000000000..b909881ba6c1
--- /dev/null
+++ b/arch/mips/cavium-octeon/crypto/octeon-md5.c
@@ -0,0 +1,216 @@
1/*
2 * Cryptographic API.
3 *
4 * MD5 Message Digest Algorithm (RFC1321).
5 *
6 * Adapted for OCTEON by Aaro Koskinen <aaro.koskinen@iki.fi>.
7 *
8 * Based on crypto/md5.c, which is:
9 *
10 * Derived from cryptoapi implementation, originally based on the
11 * public domain implementation written by Colin Plumb in 1993.
12 *
13 * Copyright (c) Cryptoapi developers.
14 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
15 *
16 * This program is free software; you can redistribute it and/or modify it
17 * under the terms of the GNU General Public License as published by the Free
18 * Software Foundation; either version 2 of the License, or (at your option)
19 * any later version.
20 */
21
22#include <crypto/md5.h>
23#include <linux/init.h>
24#include <linux/types.h>
25#include <linux/module.h>
26#include <linux/string.h>
27#include <asm/byteorder.h>
28#include <linux/cryptohash.h>
29#include <asm/octeon/octeon.h>
30#include <crypto/internal/hash.h>
31
32#include "octeon-crypto.h"
33
34/*
35 * We pass everything as 64-bit. OCTEON can handle misaligned data.
36 */
37
38static void octeon_md5_store_hash(struct md5_state *ctx)
39{
40 u64 *hash = (u64 *)ctx->hash;
41
42 write_octeon_64bit_hash_dword(hash[0], 0);
43 write_octeon_64bit_hash_dword(hash[1], 1);
44}
45
46static void octeon_md5_read_hash(struct md5_state *ctx)
47{
48 u64 *hash = (u64 *)ctx->hash;
49
50 hash[0] = read_octeon_64bit_hash_dword(0);
51 hash[1] = read_octeon_64bit_hash_dword(1);
52}
53
54static void octeon_md5_transform(const void *_block)
55{
56 const u64 *block = _block;
57
58 write_octeon_64bit_block_dword(block[0], 0);
59 write_octeon_64bit_block_dword(block[1], 1);
60 write_octeon_64bit_block_dword(block[2], 2);
61 write_octeon_64bit_block_dword(block[3], 3);
62 write_octeon_64bit_block_dword(block[4], 4);
63 write_octeon_64bit_block_dword(block[5], 5);
64 write_octeon_64bit_block_dword(block[6], 6);
65 octeon_md5_start(block[7]);
66}
67
68static int octeon_md5_init(struct shash_desc *desc)
69{
70 struct md5_state *mctx = shash_desc_ctx(desc);
71
72 mctx->hash[0] = cpu_to_le32(0x67452301);
73 mctx->hash[1] = cpu_to_le32(0xefcdab89);
74 mctx->hash[2] = cpu_to_le32(0x98badcfe);
75 mctx->hash[3] = cpu_to_le32(0x10325476);
76 mctx->byte_count = 0;
77
78 return 0;
79}
80
81static int octeon_md5_update(struct shash_desc *desc, const u8 *data,
82 unsigned int len)
83{
84 struct md5_state *mctx = shash_desc_ctx(desc);
85 const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);
86 struct octeon_cop2_state state;
87 unsigned long flags;
88
89 mctx->byte_count += len;
90
91 if (avail > len) {
92 memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
93 data, len);
94 return 0;
95 }
96
97 memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), data,
98 avail);
99
100 local_bh_disable();
101 preempt_disable();
102 flags = octeon_crypto_enable(&state);
103 octeon_md5_store_hash(mctx);
104
105 octeon_md5_transform(mctx->block);
106 data += avail;
107 len -= avail;
108
109 while (len >= sizeof(mctx->block)) {
110 octeon_md5_transform(data);
111 data += sizeof(mctx->block);
112 len -= sizeof(mctx->block);
113 }
114
115 octeon_md5_read_hash(mctx);
116 octeon_crypto_disable(&state, flags);
117 preempt_enable();
118 local_bh_enable();
119
120 memcpy(mctx->block, data, len);
121
122 return 0;
123}
124
125static int octeon_md5_final(struct shash_desc *desc, u8 *out)
126{
127 struct md5_state *mctx = shash_desc_ctx(desc);
128 const unsigned int offset = mctx->byte_count & 0x3f;
129 char *p = (char *)mctx->block + offset;
130 int padding = 56 - (offset + 1);
131 struct octeon_cop2_state state;
132 unsigned long flags;
133
134 *p++ = 0x80;
135
136 local_bh_disable();
137 preempt_disable();
138 flags = octeon_crypto_enable(&state);
139 octeon_md5_store_hash(mctx);
140
141 if (padding < 0) {
142 memset(p, 0x00, padding + sizeof(u64));
143 octeon_md5_transform(mctx->block);
144 p = (char *)mctx->block;
145 padding = 56;
146 }
147
148 memset(p, 0, padding);
149 mctx->block[14] = cpu_to_le32(mctx->byte_count << 3);
150 mctx->block[15] = cpu_to_le32(mctx->byte_count >> 29);
151 octeon_md5_transform(mctx->block);
152
153 octeon_md5_read_hash(mctx);
154 octeon_crypto_disable(&state, flags);
155 preempt_enable();
156 local_bh_enable();
157
158 memcpy(out, mctx->hash, sizeof(mctx->hash));
159 memset(mctx, 0, sizeof(*mctx));
160
161 return 0;
162}
163
164static int octeon_md5_export(struct shash_desc *desc, void *out)
165{
166 struct md5_state *ctx = shash_desc_ctx(desc);
167
168 memcpy(out, ctx, sizeof(*ctx));
169 return 0;
170}
171
172static int octeon_md5_import(struct shash_desc *desc, const void *in)
173{
174 struct md5_state *ctx = shash_desc_ctx(desc);
175
176 memcpy(ctx, in, sizeof(*ctx));
177 return 0;
178}
179
180static struct shash_alg alg = {
181 .digestsize = MD5_DIGEST_SIZE,
182 .init = octeon_md5_init,
183 .update = octeon_md5_update,
184 .final = octeon_md5_final,
185 .export = octeon_md5_export,
186 .import = octeon_md5_import,
187 .descsize = sizeof(struct md5_state),
188 .statesize = sizeof(struct md5_state),
189 .base = {
190 .cra_name = "md5",
191 .cra_driver_name= "octeon-md5",
192 .cra_priority = OCTEON_CR_OPCODE_PRIORITY,
193 .cra_flags = CRYPTO_ALG_TYPE_SHASH,
194 .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
195 .cra_module = THIS_MODULE,
196 }
197};
198
199static int __init md5_mod_init(void)
200{
201 if (!octeon_has_crypto())
202 return -ENOTSUPP;
203 return crypto_register_shash(&alg);
204}
205
206static void __exit md5_mod_fini(void)
207{
208 crypto_unregister_shash(&alg);
209}
210
211module_init(md5_mod_init);
212module_exit(md5_mod_fini);
213
214MODULE_LICENSE("GPL");
215MODULE_DESCRIPTION("MD5 Message Digest Algorithm (OCTEON)");
216MODULE_AUTHOR("Aaro Koskinen <aaro.koskinen@iki.fi>");
diff --git a/arch/mips/cavium-octeon/executive/octeon-model.c b/arch/mips/cavium-octeon/executive/octeon-model.c
index e15b049b3bd7..b2104bd9ab3b 100644
--- a/arch/mips/cavium-octeon/executive/octeon-model.c
+++ b/arch/mips/cavium-octeon/executive/octeon-model.c
@@ -27,6 +27,9 @@
27 27
28#include <asm/octeon/octeon.h> 28#include <asm/octeon/octeon.h>
29 29
30enum octeon_feature_bits __octeon_feature_bits __read_mostly;
31EXPORT_SYMBOL_GPL(__octeon_feature_bits);
32
30/** 33/**
31 * Read a byte of fuse data 34 * Read a byte of fuse data
32 * @byte_addr: address to read 35 * @byte_addr: address to read
@@ -103,6 +106,9 @@ static const char *__init octeon_model_get_string_buffer(uint32_t chip_id,
103 else 106 else
104 suffix = "NSP"; 107 suffix = "NSP";
105 108
109 if (!fus_dat2.s.nocrypto)
110 __octeon_feature_bits |= OCTEON_HAS_CRYPTO;
111
106 /* 112 /*
107 * Assume pass number is encoded using <5:3><2:0>. Exceptions 113 * Assume pass number is encoded using <5:3><2:0>. Exceptions
108 * will be fixed later. 114 * will be fixed later.