aboutsummaryrefslogtreecommitdiffstats
path: root/security/smc/tf_crypto.h
blob: 797b08281b06733ee2e543e3cd4ab7ba11948937 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
/**
 * Copyright (c) 2011 Trusted Logic S.A.
 * All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#ifndef __TF_PUBLIC_CRYPTO_H
#define __TF_PUBLIC_CRYPTO_H

#include "tf_defs.h"
#include <linux/io.h>
#include <mach/io.h>

#include <clockdomain.h>

#ifdef CONFIG_TF_DRIVER_CRYPTO_FIPS
#include <linux/sysdev.h>
#endif

#ifdef __ASM_ARM_ARCH_OMAP_CLOCKDOMAIN_H
#define clkdm_wakeup omap2_clkdm_wakeup
#define clkdm_allow_idle omap2_clkdm_allow_idle
#endif

/*-------------------------------------------------------------------------- */

#define PUBLIC_CRYPTO_HWA_AES1		0x1
#define PUBLIC_CRYPTO_HWA_DES		0x4
#define PUBLIC_CRYPTO_HWA_SHA		0x8

#define OUTREG32(a, b)	__raw_writel(b, a)
#define INREG32(a)	__raw_readl(a)
#define SETREG32(x, y)	OUTREG32(x, INREG32(x) | (y))
#define CLRREG32(x, y)	OUTREG32(x, INREG32(x) & ~(y))

#define PUBLIC_CRYPTO_CLKSTCTRL_CLOCK_REG	0x4A009580
#define PUBLIC_CRYPTO_AES1_CLOCK_REG		0x4A0095A0
#define PUBLIC_CRYPTO_DES3DES_CLOCK_REG		0x4A0095B0
#define PUBLIC_CRYPTO_SHA2MD5_CLOCK_REG		0x4A0095C8

#define BYTES_TO_LONG(a)(u32)(a[0] | (a[1]<<8) | (a[2]<<16) | (a[3]<<24))
#define LONG_TO_BYTE(a, b) {  a[0] = (u8)((b) & 0xFF);		 \
				a[1] = (u8)(((b) >> 8) & 0xFF);  \
				a[2] = (u8)(((b) >> 16) & 0xFF); \
				a[3] = (u8)(((b) >> 24) & 0xFF); }

#define IS_4_BYTES_ALIGNED(x)((!((x) & 0x3)) ? true : false)

#define TF_SMC_OMAP4_PUBLIC_DMA

/*
 *The size limit to trigger DMA for AES, DES and Digest.
 *0xFFFFFFFF means "never"
 */
#ifdef TF_SMC_OMAP4_PUBLIC_DMA
#define DMA_TRIGGER_IRQ_AES				128
#define DMA_TRIGGER_IRQ_DES				128
#define DMA_TRIGGER_IRQ_DIGEST				1024
#else
#define DMA_TRIGGER_IRQ_AES				0xFFFFFFFF
#define DMA_TRIGGER_IRQ_DES				0xFFFFFFFF
#define DMA_TRIGGER_IRQ_DIGEST				0xFFFFFFFF
#endif

/*Error code constants */
#define PUBLIC_CRYPTO_OPERATION_SUCCESS	0x00000000
#define PUBLIC_CRYPTO_ERR_ACCESS_DENIED	0x00000001
#define PUBLIC_CRYPTO_ERR_OUT_OF_MEMORY	0x00000002
#define PUBLIC_CRYPTO_ERR_BAD_PARAMETERS	0x00000003
#define PUBLIC_CRYPTO_ERR_TIMEOUT		0x00000004

/*DMA mode constants */
#define PUBLIC_CRYPTO_DMA_USE_NONE	0x00000000	/*No DMA used*/
/*DMA with active polling used */
#define PUBLIC_CRYPTO_DMA_USE_POLLING	0x00000001
#define PUBLIC_CRYPTO_DMA_USE_IRQ	0x00000002	/*DMA with IRQ used*/

#define PUBLIC_CRYPTO_REG_SET_BIT(x, y)	OUTREG32(x, INREG32(x) | y);
#define PUBLIC_CRYPTO_REG_UNSET_BIT(x, y)	OUTREG32(x, INREG32(x) & (~y));

#define AES_BLOCK_SIZE			16
#define DES_BLOCK_SIZE			8
#define HASH_BLOCK_SIZE			64

#define HASH_MD5_LENGTH			16
#define HASH_SHA1_LENGTH		20
#define HASH_SHA224_LENGTH		28
#define HASH_SHA256_LENGTH		32

#define PUBLIC_CRYPTO_DIGEST_MAX_SIZE	32
#define PUBLIC_CRYPTO_IV_MAX_SIZE	16

#define PUBLIC_CRYPTO_HW_CLOCK_ADDR		(0x48004A14)
#define PUBLIC_CRYPTO_HW_AUTOIDLE_ADDR		(0x48004A34)

#define PUBLIC_CRYPTO_HW_CLOCK1_ADDR		(0x48004A10)
#define PUBLIC_CRYPTO_HW_AUTOIDLE1_ADDR	(0x48004A30)

#define DIGEST_CTRL_ALGO_MD5		0
#define DIGEST_CTRL_ALGO_SHA1		1
#define DIGEST_CTRL_ALGO_SHA224		2
#define DIGEST_CTRL_ALGO_SHA256		3

/*-------------------------------------------------------------------------- */
/*
 *The magic word.
 */
#define CUS_CONTEXT_MAGIC		0x45EF683C

/*-------------------------------------------------------------------------- */
/* CUS context structure                                                     */
/*-------------------------------------------------------------------------- */

/* State of an AES operation */
struct tf_crypto_aes_operation_state {
	u32 AES_IV_0;
	u32 AES_IV_1;
	u32 AES_IV_2;
	u32 AES_IV_3;

	u32 CTRL;

	/* Only used by Linux crypto API interface */
	u32 KEY1_0;
	u32 KEY1_1;
	u32 KEY1_2;
	u32 KEY1_3;
	u32 KEY1_4;
	u32 KEY1_5;
	u32 KEY1_6;
	u32 KEY1_7;

	u32 key_is_public;
};

struct tf_crypto_des_operation_state {
	u32 DES_IV_L;
	u32 DES_IV_H;
};

#define HASH_BLOCK_BYTES_LENGTH		64

struct tf_crypto_sha_operation_state {
	/* Current digest */
	u32 SHA_DIGEST_A;
	u32 SHA_DIGEST_B;
	u32 SHA_DIGEST_C;
	u32 SHA_DIGEST_D;
	u32 SHA_DIGEST_E;
	u32 SHA_DIGEST_F;
	u32 SHA_DIGEST_G;
	u32 SHA_DIGEST_H;

	/* This buffer contains a partial chunk */
	u8 chunk_buffer[HASH_BLOCK_BYTES_LENGTH];

	/* Number of bytes stored in chunk_buffer (0..64) */
	u32 chunk_length;

	/*
	 * Total number of bytes processed so far
	 * (not including the partial chunk)
	 */
	u32 bytes_processed;

	u32 CTRL;
};

union tf_crypto_operation_state {
	struct tf_crypto_aes_operation_state aes;
	struct tf_crypto_des_operation_state des;
	struct tf_crypto_sha_operation_state sha;
};

/*
 *Fully describes a public crypto operation
 *(i.e., an operation that has a shortcut attached).
 */
struct cus_context {
	/*
	 *Identifies the public crypto operation in the list of all public
	 *operations.
	 */
	struct list_head list;

	u32 magic_number;	/*Must be set to
				 *{CUS_CONTEXT_MAGIC} */

	/*basic fields */
	u32 client_session;
	u32 command_id;
	u32 hwa_id;
	u32 hwa_ctrl;
	u32 key_context;
	union tf_crypto_operation_state operation_state;
	u32 use_count;
	bool suspended;
};

struct cus_params {
	/*fields for data processing of an update command */
	u32 input_data_length;
	u8 *input_data;
	struct tf_shmem_desc *input_shmem;

	u32 output_data_length;
	u8 *output_data;
	struct tf_shmem_desc *output_shmem;
};

/*-------------------------------------------------------------------------- */
/*
 *Public crypto API (Top level)
 */

/*
*Initialize the public crypto DMA chanels and global HWA semaphores
 */
u32 tf_crypto_init(void);

/*
 *Initialize the device context CUS fields
 *(shortcut semaphore and public CUS list)
 */
void tf_crypto_init_cus(struct tf_connection *connection);

/**
 *Terminate the public crypto (including DMA)
 */
void tf_crypto_terminate(void);

int tf_crypto_try_shortcuted_update(struct tf_connection *connection,
	struct tf_command_invoke_client_command *command,
	struct tf_answer_invoke_client_command *answer);

int tf_crypto_execute_rpc(u32 rpc_command, void *rpc_shared_buffer);

/*-------------------------------------------------------------------------- */
/*
 *Helper methods
 */
u32 tf_crypto_wait_for_ready_bit(u32 *reg, u32 bit);
void tf_crypto_wait_for_ready_bit_infinitely(u32 *reg, u32 bit);

void tf_crypto_enable_clock(uint32_t clock_paddr);
void tf_crypto_disable_clock(uint32_t clock_paddr);
u32 tf_crypto_turn_off_clocks(void);

#define LOCK_HWA	true
#define UNLOCK_HWA	false

/*---------------------------------------------------------------------------*/
/*                               AES operations                              */
/*---------------------------------------------------------------------------*/

void tf_aes_init(void);
void tf_aes_exit(void);

#ifdef CONFIG_SMC_KERNEL_CRYPTO
int register_smc_public_crypto_aes(void);
void unregister_smc_public_crypto_aes(void);
#else
static inline int register_smc_public_crypto_aes(void)
{
	return 0;
}

static inline void unregister_smc_public_crypto_aes(void) {}
#endif

/**
 *This function performs an AES update operation.
 *
 *The AES1 accelerator is assumed loaded with the correct key
 *
 *AES_CTRL:		defines the mode and direction
 *aes_state:	defines the operation IV
 *src:			Input buffer to process.
 *dest:			Output buffer containing the processed data.
 *
 *nb_blocks number of block(s)to process.
 */
bool tf_aes_update(struct tf_crypto_aes_operation_state *aes_state,
	u8 *src, u8 *dest, u32 nb_blocks);

/*---------------------------------------------------------------------------*/
/*                              DES/DES3 operations                          */
/*---------------------------------------------------------------------------*/

void tf_des_init(void);
void tf_des_exit(void);

/**
 *This function performs a DES update operation.
 *
 *The DES accelerator is assumed loaded with the correct key
 *
 *DES_CTRL:		defines the mode and direction
 *des_state:	defines the operation IV
 *src:			Input buffer to process.
 *dest:			Output buffer containing the processed data.
 *nb_blocks:		Number of block(s)to process.
 */
bool tf_des_update(u32 DES_CTRL,
	struct tf_crypto_des_operation_state *des_state,
	u8 *src, u8 *dest, u32 nb_blocks);

/*---------------------------------------------------------------------------*/
/*                               Digest operations                           */
/*---------------------------------------------------------------------------*/

void tf_digest_init(void);
void tf_digest_exit(void);

#ifdef CONFIG_SMC_KERNEL_CRYPTO
int register_smc_public_crypto_digest(void);
void unregister_smc_public_crypto_digest(void);
#else
static inline int register_smc_public_crypto_digest(void)
{
	return 0;
}

static inline void unregister_smc_public_crypto_digest(void) {}
#endif

/**
 *This function performs a HASH update Operation.
 *
 *SHA_CTRL:		defines the algorithm
 *sha_state:	State of the operation
 *data:			Input buffer to process
 *data_length:	Length in bytes of the input buffer.
 *buffer_origin: TF_BUFFER_USER or TF_BUFFER_KERNEL
 */
bool tf_digest_update(
	struct tf_crypto_sha_operation_state *sha_state,
	u8 *data, u32 data_length, unsigned int buffer_origin);

void tf_aes_pm_resume(void);

#define TF_BUFFER_USER   0
#define TF_BUFFER_KERNEL 1

#define TF_CRYPTO_ALG_MD5         0x00000001
#define TF_CRYPTO_ALG_SHA1        0x00000002
#define TF_CRYPTO_ALG_SHA224      0x00000004
#define TF_CRYPTO_ALG_SHA256      0x00000008
#define TF_CRYPTO_ALG_AES_ECB_128 0x00000100
#define TF_CRYPTO_ALG_AES_ECB_192 0x00000200
#define TF_CRYPTO_ALG_AES_ECB_256 0x00000400
#define TF_CRYPTO_ALG_AES_CBC_128 0x00000800
#define TF_CRYPTO_ALG_AES_CBC_192 0x00001000
#define TF_CRYPTO_ALG_AES_CBC_256 0x00002000
#define TF_CRYPTO_ALG_AES_CTR_128 0x00004000
#define TF_CRYPTO_ALG_AES_CTR_192 0x00008000
#define TF_CRYPTO_ALG_AES_CTR_256 0x00010000
#define TF_CRYPTO_ALG_HMAC_MD5    0x00100000
#define TF_CRYPTO_ALG_HMAC_SHA1   0x00200000
#define TF_CRYPTO_ALG_HMAC_SHA224 0x00400000
#define TF_CRYPTO_ALG_HMAC_SHA256 0x00800000
#define TF_CRYPTO_ALG_HMAC_ALL    0x00f00000

#ifdef CONFIG_TF_DRIVER_FAULT_INJECTION
extern unsigned tf_fault_injection_mask;
#endif

#ifdef CONFIG_TF_DRIVER_CRYPTO_FIPS

int __init tf_crypto_hmac_module_init(void);
void __exit tf_crypto_hmac_module_exit(void);

int __init tf_self_test_register_device(void);
void __exit tf_self_test_unregister_device(void);

int tf_self_test_post_init(struct kobject *parent);
void tf_self_test_post_exit(void);
unsigned tf_self_test_post_vectors(void);

#define TF_CRYPTO_ALG_INTEGRITY   0x04000000
extern char *tf_integrity_hmac_sha256_expected_value;

#endif /* CONFIG_TF_DRIVER_CRYPTO_FIPS */

#endif /*__TF_PUBLIC_CRYPTO_H */