diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-14 12:47:01 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-14 12:47:01 -0500 |
commit | fee5429e028c414d80d036198db30454cfd91b7a (patch) | |
tree | 485f37a974e4ab85339021c794d1782e2d761c5b /arch/mips/cavium-octeon | |
parent | 83e047c104aa95a8a683d6bd421df1551c17dbd2 (diff) | |
parent | 96692a7305c49845e3cbf5a60cfcb207c5dc4030 (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/Makefile | 1 | ||||
-rw-r--r-- | arch/mips/cavium-octeon/crypto/Makefile | 7 | ||||
-rw-r--r-- | arch/mips/cavium-octeon/crypto/octeon-crypto.c | 66 | ||||
-rw-r--r-- | arch/mips/cavium-octeon/crypto/octeon-crypto.h | 75 | ||||
-rw-r--r-- | arch/mips/cavium-octeon/crypto/octeon-md5.c | 216 | ||||
-rw-r--r-- | arch/mips/cavium-octeon/executive/octeon-model.c | 6 |
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 | |||
16 | obj-y += dma-octeon.o | 16 | obj-y += dma-octeon.o |
17 | obj-y += octeon-memcpy.o | 17 | obj-y += octeon-memcpy.o |
18 | obj-y += executive/ | 18 | obj-y += executive/ |
19 | obj-y += crypto/ | ||
19 | 20 | ||
20 | obj-$(CONFIG_MTD) += flash_setup.o | 21 | obj-$(CONFIG_MTD) += flash_setup.o |
21 | obj-$(CONFIG_SMP) += smp.o | 22 | obj-$(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 | |||
5 | obj-y += octeon-crypto.o | ||
6 | |||
7 | obj-$(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 | */ | ||
26 | unsigned 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 | } | ||
44 | EXPORT_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 | */ | ||
54 | void 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 | } | ||
66 | EXPORT_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 | |||
19 | extern unsigned long octeon_crypto_enable(struct octeon_cop2_state *state); | ||
20 | extern 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) \ | ||
31 | do { \ | ||
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) \ | ||
57 | do { \ | ||
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) \ | ||
68 | do { \ | ||
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 | |||
38 | static 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 | |||
46 | static 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 | |||
54 | static 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 | |||
68 | static 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 | |||
81 | static 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 | |||
125 | static 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 | |||
164 | static 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 | |||
172 | static 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 | |||
180 | static 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 | |||
199 | static int __init md5_mod_init(void) | ||
200 | { | ||
201 | if (!octeon_has_crypto()) | ||
202 | return -ENOTSUPP; | ||
203 | return crypto_register_shash(&alg); | ||
204 | } | ||
205 | |||
206 | static void __exit md5_mod_fini(void) | ||
207 | { | ||
208 | crypto_unregister_shash(&alg); | ||
209 | } | ||
210 | |||
211 | module_init(md5_mod_init); | ||
212 | module_exit(md5_mod_fini); | ||
213 | |||
214 | MODULE_LICENSE("GPL"); | ||
215 | MODULE_DESCRIPTION("MD5 Message Digest Algorithm (OCTEON)"); | ||
216 | MODULE_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 | ||
30 | enum octeon_feature_bits __octeon_feature_bits __read_mostly; | ||
31 | EXPORT_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. |