Root/target/linux/ubicom32/files/arch/ubicom32/crypto/crypto_ubicom32.h

1/*
2 * arch/ubicom32/crypto/crypto_ubicom32.h
3 * Support for Ubicom32 cryptographic instructions.
4 *
5 * (C) Copyright 2009, Ubicom, Inc.
6 *
7 * This file is part of the Ubicom32 Linux Kernel Port.
8 *
9 * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10 * it and/or modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation, either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * The Ubicom32 Linux Kernel Port is distributed in the hope that it
15 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17 * the GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with the Ubicom32 Linux Kernel Port. If not,
21 * see <http://www.gnu.org/licenses/>.
22 *
23 * Ubicom32 implementation derived from (with many thanks):
24 * arch/m68knommu
25 * arch/blackfin
26 * arch/parisc
27 */
28#ifndef _CRYPTO_ARCH_UBICOM32_CRYPT_H
29#define _CRYPTO_ARCH_UBICOM32_CRYPT_H
30
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/jiffies.h>
34#include <linux/timer.h>
35#include <linux/spinlock.h>
36#include <asm/errno.h>
37#include <asm/io.h>
38#include <asm/ip5000.h>
39
40#define CRYPTO_UBICOM32_LOOP_ASM 1
41#define CRYPTO_UBICOM32_ALIGNMENT 4
42#define SEC_ALIGNED(p) (((u32)p & 3) == 0)
43
44#define SEC_BASE SECURITY_BASE
45#define SEC_KEY_OFFSET SECURITY_KEY_VALUE(0)
46#define SEC_INPUT_OFFSET SECURITY_KEY_IN(0)
47#define SEC_OUTPUT_OFFSET SECURITY_KEY_OUT(0)
48#define SEC_HASH_OFFSET SECURITY_KEY_HASH(0)
49
50#define SEC_KEY_128_BITS SECURITY_CTRL_KEY_SIZE(0)
51#define SEC_KEY_192_BITS SECURITY_CTRL_KEY_SIZE(1)
52#define SEC_KEY_256_BITS SECURITY_CTRL_KEY_SIZE(2)
53
54#define SEC_HASH_NONE SECURITY_CTRL_HASH_ALG_NONE
55#define SEC_HASH_MD5 SECURITY_CTRL_HASH_ALG_MD5
56#define SEC_HASH_SHA1 SECURITY_CTRL_HASH_ALG_SHA1
57
58#define SEC_CBC_SET SECURITY_CTRL_CBC
59#define SEC_CBC_NONE 0
60
61#define SEC_ALG_AES SECURITY_CTRL_CIPHER_ALG_AES
62#define SEC_ALG_NONE SECURITY_CTRL_CIPHER_ALG_NONE
63#define SEC_ALG_DES SECURITY_CTRL_CIPHER_ALG_DES
64#define SEC_ALG_3DES SECURITY_CTRL_CIPHER_ALG_3DES
65
66#define SEC_DIR_ENCRYPT SECURITY_CTRL_ENCIPHER
67#define SEC_DIR_DECRYPT 0
68
69#define CRYPTO_UBICOM32_PRIORITY 300
70#define CRYPTO_UBICOM32_COMPOSITE_PRIORITY 400
71
72#define HW_CRYPTO_PS_MAX_IDLE_MS 100 /* idle time (ms) before shuting down sm */
73
74extern spinlock_t crypto_ubicom32_lock;
75extern bool crypto_ubicom32_inited;
76extern volatile bool crypto_ubicom32_on;
77extern volatile unsigned long crypto_ubicom32_last_use;
78extern struct timer_list crypto_ubicom32_ps_timer;
79extern void crypto_ubicom32_ps_check(unsigned long data);
80
81#define SEC_COPY_2W(t, s) \
82    asm volatile ( \
83    " move.4 0(%0), 0(%1) \n\t" \
84    " move.4 4(%0), 4(%1) \n\t" \
85                            \
86        : \
87        : "a" (t), "a" (s) \
88    )
89
90#define SEC_COPY_4W(t, s) \
91    asm volatile ( \
92    " move.4 0(%0), 0(%1) \n\t" \
93    " move.4 4(%0), 4(%1) \n\t" \
94    " move.4 8(%0), 8(%1) \n\t" \
95    " move.4 12(%0), 12(%1) \n\t" \
96        : \
97        : "a" (t), "a" (s) \
98    )
99
100#define SEC_COPY_5W(t, s) \
101    asm volatile ( \
102    " move.4 0(%0), 0(%1) \n\t" \
103    " move.4 4(%0), 4(%1) \n\t" \
104    " move.4 8(%0), 8(%1) \n\t" \
105    " move.4 12(%0), 12(%1) \n\t" \
106    " move.4 16(%0), 16(%1) \n\t" \
107        : \
108        : "a" (t), "a" (s) \
109    )
110
111#define SEC_SET_KEY_2W(x) \
112    asm volatile ( \
113    " ; write key to Security Keyblock \n\t" \
114    " move.4 0x10(%0), 0(%1) \n\t" \
115    " move.4 0x14(%0), 4(%1) \n\t" \
116        : \
117        : "a" (SECURITY_BASE), "a" (x) \
118    )
119
120#define SEC_SET_KEY_4W(x) \
121    asm volatile ( \
122    " ; write key to Security Keyblock \n\t" \
123    " move.4 0x10(%0), 0(%1) \n\t" \
124    " move.4 0x14(%0), 4(%1) \n\t" \
125    " move.4 0x18(%0), 8(%1) \n\t" \
126    " move.4 0x1c(%0), 12(%1) \n\t" \
127        : \
128        : "a"(SECURITY_BASE), "a"(x) \
129    )
130
131#define SEC_SET_KEY_6W(x) \
132    asm volatile ( \
133    " ; write key to Security Keyblock \n\t" \
134    " move.4 0x10(%0), 0(%1) \n\t" \
135    " move.4 0x14(%0), 4(%1) \n\t" \
136    " move.4 0x18(%0), 8(%1) \n\t" \
137    " move.4 0x1c(%0), 12(%1) \n\t" \
138    " move.4 0x20(%0), 16(%1) \n\t" \
139    " move.4 0x24(%0), 20(%1) \n\t" \
140        : \
141        : "a" (SECURITY_BASE), "a" (x) \
142    )
143
144#define SEC_SET_KEY_8W(x) \
145    asm volatile ( \
146    " ; write key to Security Keyblock \n\t" \
147    " move.4 0x10(%0), 0(%1) \n\t" \
148    " move.4 0x14(%0), 4(%1) \n\t" \
149    " move.4 0x18(%0), 8(%1) \n\t" \
150    " move.4 0x1c(%0), 12(%1) \n\t" \
151    " move.4 0x20(%0), 16(%1) \n\t" \
152    " move.4 0x24(%0), 20(%1) \n\t" \
153    " move.4 0x28(%0), 24(%1) \n\t" \
154    " move.4 0x2c(%0), 28(%1) \n\t" \
155        : \
156        : "a" (SECURITY_BASE), "a" (x) \
157    )
158
159#define SEC_SET_KEY_64(k) SEC_SET_KEY_2W(k)
160#define SEC_SET_KEY_128(k) SEC_SET_KEY_4W(k)
161#define SEC_SET_KEY_192(k) SEC_SET_KEY_6W(k)
162#define SEC_SET_KEY_256(k) SEC_SET_KEY_8W(k)
163
164#define DES_SET_KEY(x) SEC_SET_KEY_64(x)
165#define DES3_SET_KEY(x) SEC_SET_KEY_192(x)
166
167#define SEC_SET_INPUT_2W(x) \
168    asm volatile ( \
169    " ; write key to Security Keyblock \n\t" \
170    " move.4 0x30(%0), 0(%1) \n\t" \
171    " move.4 0x34(%0), 4(%1) \n\t" \
172        : \
173        : "a" (SECURITY_BASE), "a" (x) \
174    )
175
176#define SEC_GET_OUTPUT_2W(x) \
177    asm volatile ( \
178    " ; write key to Security Keyblock \n\t" \
179    " move.4 0(%1), 0x50(%0) \n\t" \
180    " move.4 4(%1), 0x54(%0) \n\t" \
181        : \
182        : "a" (SECURITY_BASE), "a" (x) \
183    )
184
185#define SEC_SET_INPUT_4W(x) \
186    asm volatile ( \
187    " ; write key to Security Keyblock \n\t" \
188    " move.4 0x30(%0), 0(%1) \n\t" \
189    " move.4 0x34(%0), 4(%1) \n\t" \
190    " move.4 0x38(%0), 8(%1) \n\t" \
191    " move.4 0x3c(%0), 12(%1) \n\t" \
192        : \
193        : "a" (SECURITY_BASE), "a" (x) \
194    )
195
196#define SEC_GET_OUTPUT_4W(x) \
197    asm volatile ( \
198    " ; read output from Security Keyblock \n\t" \
199    " move.4 0(%1), 0x50(%0) \n\t" \
200    " move.4 4(%1), 0x54(%0) \n\t" \
201    " move.4 8(%1), 0x58(%0) \n\t" \
202    " move.4 12(%1), 0x5c(%0) \n\t" \
203        : \
204        : "a" (SECURITY_BASE), "a" (x) \
205    )
206
207#define SEC_SET_IV_4W(x) \
208    asm volatile ( \
209    " ; write IV to Security Keyblock \n\t" \
210    " move.4 0x50(%0), 0(%1) \n\t" \
211    " move.4 0x54(%0), 4(%1) \n\t" \
212    " move.4 0x58(%0), 8(%1) \n\t" \
213    " move.4 0x5c(%0), 12(%1) \n\t" \
214        : \
215        : "a" (SECURITY_BASE), "a" (x) \
216    )
217
218#define SEC_PIPE_FLUSH() asm volatile ( " pipe_flush 0 \n\t" )
219
220static inline void hw_crypto_set_ctrl(uint32_t c)
221{
222    asm volatile (
223    " move.4 0(%0), %1 \n\t"
224        :
225        : "a" (SECURITY_BASE + SECURITY_CTRL), "d" (c)
226    );
227}
228
229static inline void hw_crypto_ps_start(void)
230{
231    crypto_ubicom32_ps_timer.expires = jiffies + msecs_to_jiffies(HW_CRYPTO_PS_MAX_IDLE_MS >> 1);
232    add_timer(&crypto_ubicom32_ps_timer);
233}
234
235static inline void hw_crypto_turn_on(void)
236{
237    asm volatile (
238    " moveai A4, %0 \n\t"
239    " bset 0x0(A4), 0x0(A4), %1 \n\t"
240    " cycles 11 \n\t"
241        :
242        : "i" (OCP_BASE >> 7), "i" (GEN_CLK_PLL_SECURITY_BIT_NO)
243        : "a4", "cc"
244    );
245    crypto_ubicom32_on = true;
246}
247
248static inline void hw_crypto_turn_off(void)
249{
250    asm volatile (
251    " moveai A4, %0 \n\t"
252    " bclr 0x0(A4), 0x0(A4), %1 \n\t"
253        :
254        : "i" (OCP_BASE >> 7), "i" (GEN_CLK_PLL_SECURITY_BIT_NO)
255        : "a4", "cc"
256    );
257    crypto_ubicom32_on = false;
258}
259
260/*
261 * hw_crypto_check
262 * Most probably hw crypto is called in clusters and it makes no sense to turn it off
263 * and on and waster 13 cycles every time.
264 */
265static inline void hw_crypto_check(void)
266{
267    if (likely(crypto_ubicom32_on)) {
268        return;
269    }
270    crypto_ubicom32_last_use = jiffies;
271    hw_crypto_turn_on();
272    hw_crypto_ps_start();
273}
274
275/*
276 * hw_crypto_ps_init
277 * Init power save timer
278 */
279static inline void hw_crypto_ps_init(void)
280{
281    init_timer_deferrable(&crypto_ubicom32_ps_timer);
282    crypto_ubicom32_ps_timer.function = crypto_ubicom32_ps_check;
283    crypto_ubicom32_ps_timer.data = 0;
284}
285
286/*
287 * hw_crypto_init()
288 * Initialize OCP security module lock and disables its clock.
289 */
290static inline void hw_crypto_init(void)
291{
292    if (!crypto_ubicom32_inited) {
293        crypto_ubicom32_inited = true;
294        spin_lock_init(&crypto_ubicom32_lock);
295        hw_crypto_ps_init();
296        hw_crypto_turn_off();
297    }
298}
299
300/*
301 * hw_crypto_lock()
302 * Locks the OCP security module and enables its clock.
303 */
304static inline void hw_crypto_lock(void)
305{
306    spin_lock_bh(&crypto_ubicom32_lock);
307}
308
309/*
310 * hw_crypto_unlock()
311 * Unlocks the OCP security module and disables its clock.
312 */
313static inline void hw_crypto_unlock(void)
314{
315    crypto_ubicom32_last_use = jiffies;
316    spin_unlock_bh(&crypto_ubicom32_lock);
317}
318
319#define CONFIG_CRYPTO_UBICOM32_DEBUG 1
320
321#ifdef CONFIG_CRYPTO_UBICOM32_DEBUG
322static inline void hex_dump(void *buf, int b_size, const char *msg)
323{
324    u8 *b = (u8 *)buf;
325    int i;
326    if (msg) {
327        printk("%s:\t", msg);
328    }
329
330    for (i=0; i < b_size; i++) {
331        printk("%02x ", b[i]);
332        if ((i & 3) == 3) {
333            printk(" ");
334        }
335        if ((i & 31) == 31) {
336            printk("\n");
337        }
338    }
339    printk("\n");
340}
341#define UBICOM32_SEC_DUMP(a, b, c) hex_dump(a, b, c)
342#else
343#define UBICOM32_SEC_DUMP(a, b, c)
344#endif
345
346#endif /* _CRYPTO_ARCH_UBICOM32_CRYPT_H */
347

Archive Download this file



interactive