xref: /optee_os/lib/libutee/tee_api_operations.c (revision 316a94e710afc8dcb5b6ac991741ac6370af65fc)
1 /*
2  * Copyright (c) 2014, STMicroelectronics International N.V.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27 #include <stdlib.h>
28 #include <string.h>
29 #include <string_ext.h>
30 
31 #include <tee_api.h>
32 #include <tee_api_defines_extensions.h>
33 #include <tee_internal_api_extensions.h>
34 #include <utee_syscalls.h>
35 #include <utee_defines.h>
36 #include <util.h>
37 
38 struct __TEE_OperationHandle {
39 	TEE_OperationInfo info;
40 	TEE_ObjectHandle key1;
41 	TEE_ObjectHandle key2;
42 	uint8_t *buffer;	/* buffer to collect complete blocks */
43 	bool buffer_two_blocks;	/* True if two blocks need to be buffered */
44 	size_t block_size;	/* Block size of cipher */
45 	size_t buffer_offs;	/* Offset in buffer */
46 	uint32_t state;		/* Handle to state in TEE Core */
47 	uint32_t ae_tag_len;	/*
48 				 * tag_len in bytes for AE operation else unused
49 				 */
50 };
51 
52 /* Cryptographic Operations API - Generic Operation Functions */
53 
54 TEE_Result TEE_AllocateOperation(TEE_OperationHandle *operation,
55 				 uint32_t algorithm, uint32_t mode,
56 				 uint32_t maxKeySize)
57 {
58 	TEE_Result res;
59 	TEE_OperationHandle op = TEE_HANDLE_NULL;
60 	uint32_t handle_state = 0;
61 	size_t block_size = 1;
62 	uint32_t req_key_usage;
63 	bool with_private_key = false;
64 	bool buffer_two_blocks = false;
65 
66 	if (operation == NULL)
67 		TEE_Panic(0);
68 
69 	if (algorithm == TEE_ALG_AES_XTS)
70 		handle_state = TEE_HANDLE_FLAG_EXPECT_TWO_KEYS;
71 
72 	/* Check algorithm max key size */
73 	switch (algorithm) {
74 	case TEE_ALG_DSA_SHA1:
75 		if (maxKeySize < 512)
76 			return TEE_ERROR_NOT_SUPPORTED;
77 		if (maxKeySize > 1024)
78 			return TEE_ERROR_NOT_SUPPORTED;
79 		if (maxKeySize % 64 != 0)
80 			return TEE_ERROR_NOT_SUPPORTED;
81 		break;
82 
83 	case TEE_ALG_DSA_SHA224:
84 		if (maxKeySize != 2048)
85 			return TEE_ERROR_NOT_SUPPORTED;
86 		break;
87 
88 	case TEE_ALG_DSA_SHA256:
89 		if (maxKeySize != 2048 && maxKeySize != 3072)
90 			return TEE_ERROR_NOT_SUPPORTED;
91 		break;
92 
93 	case TEE_ALG_ECDSA_P192:
94 	case TEE_ALG_ECDH_P192:
95 		if (maxKeySize != 192)
96 			return TEE_ERROR_NOT_SUPPORTED;
97 		break;
98 
99 	case TEE_ALG_ECDSA_P224:
100 	case TEE_ALG_ECDH_P224:
101 		if (maxKeySize != 224)
102 			return TEE_ERROR_NOT_SUPPORTED;
103 		break;
104 
105 	case TEE_ALG_ECDSA_P256:
106 	case TEE_ALG_ECDH_P256:
107 		if (maxKeySize != 256)
108 			return TEE_ERROR_NOT_SUPPORTED;
109 		break;
110 
111 	case TEE_ALG_ECDSA_P384:
112 	case TEE_ALG_ECDH_P384:
113 		if (maxKeySize != 384)
114 			return TEE_ERROR_NOT_SUPPORTED;
115 		break;
116 
117 	case TEE_ALG_ECDSA_P521:
118 	case TEE_ALG_ECDH_P521:
119 		if (maxKeySize != 521)
120 			return TEE_ERROR_NOT_SUPPORTED;
121 		break;
122 
123 	default:
124 		break;
125 	}
126 
127 	/* Check algorithm mode */
128 	switch (algorithm) {
129 	case TEE_ALG_AES_CTS:
130 	case TEE_ALG_AES_XTS:
131 		buffer_two_blocks = true;
132 	 /*FALLTHROUGH*/ case TEE_ALG_AES_ECB_NOPAD:
133 	case TEE_ALG_AES_CBC_NOPAD:
134 	case TEE_ALG_AES_CTR:
135 	case TEE_ALG_AES_CCM:
136 	case TEE_ALG_AES_GCM:
137 	case TEE_ALG_DES_ECB_NOPAD:
138 	case TEE_ALG_DES_CBC_NOPAD:
139 	case TEE_ALG_DES3_ECB_NOPAD:
140 	case TEE_ALG_DES3_CBC_NOPAD:
141 		if (TEE_ALG_GET_MAIN_ALG(algorithm) == TEE_MAIN_ALGO_AES)
142 			block_size = TEE_AES_BLOCK_SIZE;
143 		else
144 			block_size = TEE_DES_BLOCK_SIZE;
145 
146 		if (mode == TEE_MODE_ENCRYPT)
147 			req_key_usage = TEE_USAGE_ENCRYPT;
148 		else if (mode == TEE_MODE_DECRYPT)
149 			req_key_usage = TEE_USAGE_DECRYPT;
150 		else
151 			return TEE_ERROR_NOT_SUPPORTED;
152 		break;
153 
154 	case TEE_ALG_RSASSA_PKCS1_V1_5_MD5:
155 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1:
156 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224:
157 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256:
158 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384:
159 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512:
160 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1:
161 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224:
162 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256:
163 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384:
164 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512:
165 	case TEE_ALG_DSA_SHA1:
166 	case TEE_ALG_DSA_SHA224:
167 	case TEE_ALG_DSA_SHA256:
168 	case TEE_ALG_ECDSA_P192:
169 	case TEE_ALG_ECDSA_P224:
170 	case TEE_ALG_ECDSA_P256:
171 	case TEE_ALG_ECDSA_P384:
172 	case TEE_ALG_ECDSA_P521:
173 		if (mode == TEE_MODE_SIGN) {
174 			with_private_key = true;
175 			req_key_usage = TEE_USAGE_SIGN;
176 		} else if (mode == TEE_MODE_VERIFY) {
177 			req_key_usage = TEE_USAGE_VERIFY;
178 		} else {
179 			return TEE_ERROR_NOT_SUPPORTED;
180 		}
181 		break;
182 
183 	case TEE_ALG_RSAES_PKCS1_V1_5:
184 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1:
185 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224:
186 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256:
187 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384:
188 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512:
189 		if (mode == TEE_MODE_ENCRYPT) {
190 			req_key_usage = TEE_USAGE_ENCRYPT;
191 		} else if (mode == TEE_MODE_DECRYPT) {
192 			with_private_key = true;
193 			req_key_usage = TEE_USAGE_DECRYPT;
194 		} else {
195 			return TEE_ERROR_NOT_SUPPORTED;
196 		}
197 		break;
198 
199 	case TEE_ALG_RSA_NOPAD:
200 		if (mode == TEE_MODE_ENCRYPT) {
201 			req_key_usage = TEE_USAGE_ENCRYPT | TEE_USAGE_VERIFY;
202 		} else if (mode == TEE_MODE_DECRYPT) {
203 			with_private_key = true;
204 			req_key_usage = TEE_USAGE_DECRYPT | TEE_USAGE_SIGN;
205 		} else {
206 			return TEE_ERROR_NOT_SUPPORTED;
207 		}
208 		break;
209 
210 	case TEE_ALG_DH_DERIVE_SHARED_SECRET:
211 	case TEE_ALG_ECDH_P192:
212 	case TEE_ALG_ECDH_P224:
213 	case TEE_ALG_ECDH_P256:
214 	case TEE_ALG_ECDH_P384:
215 	case TEE_ALG_ECDH_P521:
216 	case TEE_ALG_HKDF_MD5_DERIVE_KEY:
217 	case TEE_ALG_HKDF_SHA1_DERIVE_KEY:
218 	case TEE_ALG_HKDF_SHA224_DERIVE_KEY:
219 	case TEE_ALG_HKDF_SHA256_DERIVE_KEY:
220 	case TEE_ALG_HKDF_SHA384_DERIVE_KEY:
221 	case TEE_ALG_HKDF_SHA512_DERIVE_KEY:
222 	case TEE_ALG_CONCAT_KDF_SHA1_DERIVE_KEY:
223 	case TEE_ALG_CONCAT_KDF_SHA224_DERIVE_KEY:
224 	case TEE_ALG_CONCAT_KDF_SHA256_DERIVE_KEY:
225 	case TEE_ALG_CONCAT_KDF_SHA384_DERIVE_KEY:
226 	case TEE_ALG_CONCAT_KDF_SHA512_DERIVE_KEY:
227 	case TEE_ALG_PBKDF2_HMAC_SHA1_DERIVE_KEY:
228 		if (mode != TEE_MODE_DERIVE)
229 			return TEE_ERROR_NOT_SUPPORTED;
230 		with_private_key = true;
231 		req_key_usage = TEE_USAGE_DERIVE;
232 		break;
233 
234 	case TEE_ALG_MD5:
235 	case TEE_ALG_SHA1:
236 	case TEE_ALG_SHA224:
237 	case TEE_ALG_SHA256:
238 	case TEE_ALG_SHA384:
239 	case TEE_ALG_SHA512:
240 		if (mode != TEE_MODE_DIGEST)
241 			return TEE_ERROR_NOT_SUPPORTED;
242 		handle_state |= TEE_HANDLE_FLAG_KEY_SET;
243 		req_key_usage = 0;
244 		break;
245 
246 	case TEE_ALG_DES_CBC_MAC_NOPAD:
247 	case TEE_ALG_AES_CBC_MAC_NOPAD:
248 	case TEE_ALG_AES_CBC_MAC_PKCS5:
249 	case TEE_ALG_AES_CMAC:
250 	case TEE_ALG_DES_CBC_MAC_PKCS5:
251 	case TEE_ALG_DES3_CBC_MAC_NOPAD:
252 	case TEE_ALG_DES3_CBC_MAC_PKCS5:
253 	case TEE_ALG_HMAC_MD5:
254 	case TEE_ALG_HMAC_SHA1:
255 	case TEE_ALG_HMAC_SHA224:
256 	case TEE_ALG_HMAC_SHA256:
257 	case TEE_ALG_HMAC_SHA384:
258 	case TEE_ALG_HMAC_SHA512:
259 		if (mode != TEE_MODE_MAC)
260 			return TEE_ERROR_NOT_SUPPORTED;
261 		req_key_usage = TEE_USAGE_MAC;
262 		break;
263 
264 	default:
265 		return TEE_ERROR_NOT_SUPPORTED;
266 	}
267 
268 	op = TEE_Malloc(sizeof(*op), 0);
269 	if (op == NULL)
270 		return TEE_ERROR_OUT_OF_MEMORY;
271 
272 	op->info.algorithm = algorithm;
273 	op->info.operationClass = TEE_ALG_GET_CLASS(algorithm);
274 	op->info.mode = mode;
275 	op->info.maxKeySize = maxKeySize;
276 	op->info.requiredKeyUsage = req_key_usage;
277 	op->info.handleState = handle_state;
278 
279 	if (block_size > 1) {
280 		size_t buffer_size = block_size;
281 
282 		if (buffer_two_blocks)
283 			buffer_size *= 2;
284 
285 		op->buffer =
286 		    TEE_Malloc(buffer_size, TEE_USER_MEM_HINT_NO_FILL_ZERO);
287 		if (op->buffer == NULL) {
288 			res = TEE_ERROR_OUT_OF_MEMORY;
289 			goto out;
290 		}
291 	}
292 	op->block_size = block_size;
293 	op->buffer_two_blocks = buffer_two_blocks;
294 
295 	if (TEE_ALG_GET_CLASS(algorithm) != TEE_OPERATION_DIGEST) {
296 		uint32_t mks = maxKeySize;
297 		TEE_ObjectType key_type = TEE_ALG_GET_KEY_TYPE(algorithm,
298 						       with_private_key);
299 
300 		/*
301 		 * If two keys are expected the max key size is the sum of
302 		 * the size of both keys.
303 		 */
304 		if (op->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS)
305 			mks /= 2;
306 
307 		res = TEE_AllocateTransientObject(key_type, mks, &op->key1);
308 		if (res != TEE_SUCCESS)
309 			goto out;
310 
311 		if ((op->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) !=
312 		    0) {
313 			res =
314 			    TEE_AllocateTransientObject(key_type, mks,
315 							&op->key2);
316 			if (res != TEE_SUCCESS)
317 				goto out;
318 		}
319 	}
320 
321 	res = utee_cryp_state_alloc(algorithm, mode, (uint32_t) op->key1,
322 				    (uint32_t) op->key2, &op->state);
323 	if (res != TEE_SUCCESS)
324 		goto out;
325 
326 	/* For multi-stage operation do an "init". */
327 	TEE_ResetOperation(op);
328 	*operation = op;
329 
330 out:
331 	if (res != TEE_SUCCESS) {
332 		TEE_FreeTransientObject(op->key1);
333 		TEE_FreeTransientObject(op->key2);
334 		TEE_FreeOperation(op);
335 	}
336 
337 	return res;
338 }
339 
340 void TEE_FreeOperation(TEE_OperationHandle operation)
341 {
342 	if (operation != TEE_HANDLE_NULL) {
343 		/*
344 		 * Note that keys should not be freed here, since they are
345 		 * claimed by the operation they will be freed by
346 		 * utee_cryp_state_free().
347 		 */
348 		utee_cryp_state_free(operation->state);
349 		TEE_Free(operation->buffer);
350 		TEE_Free(operation);
351 	}
352 }
353 
354 void TEE_GetOperationInfo(TEE_OperationHandle operation,
355 			  TEE_OperationInfo *operationInfo)
356 {
357 	if (operation == TEE_HANDLE_NULL)
358 		TEE_Panic(0);
359 
360 	if (operationInfo == NULL)
361 		TEE_Panic(0);
362 
363 	*operationInfo = operation->info;
364 }
365 
366 void TEE_ResetOperation(TEE_OperationHandle operation)
367 {
368 	TEE_Result res;
369 
370 	if (operation == TEE_HANDLE_NULL)
371 		TEE_Panic(0);
372 	if (operation->info.operationClass == TEE_OPERATION_DIGEST) {
373 		res = utee_hash_init(operation->state, NULL, 0);
374 		if (res != TEE_SUCCESS)
375 			TEE_Panic(res);
376 	}
377 	operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED;
378 }
379 
380 TEE_Result TEE_SetOperationKey(TEE_OperationHandle operation,
381 			       TEE_ObjectHandle key)
382 {
383 	TEE_Result res;
384 	uint32_t key_size = 0;
385 
386 	if (operation == TEE_HANDLE_NULL)
387 		TEE_Panic(0);
388 
389 	/* No key for digests */
390 	if (operation->info.operationClass == TEE_OPERATION_DIGEST)
391 		TEE_Panic(0);
392 
393 	/* Two keys expected */
394 	if ((operation->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) !=
395 	    0)
396 		TEE_Panic(0);
397 
398 	if (key != TEE_HANDLE_NULL) {
399 		TEE_ObjectInfo key_info;
400 
401 		res = TEE_GetObjectInfo1(key, &key_info);
402 		if (res != TEE_SUCCESS)
403 			goto err;
404 
405 		/* Supplied key has to meet required usage */
406 		if ((key_info.objectUsage & operation->info.requiredKeyUsage) !=
407 		    operation->info.requiredKeyUsage) {
408 			TEE_Panic(0);
409 		}
410 
411 		if (operation->info.maxKeySize < key_info.keySize)
412 			TEE_Panic(0);
413 
414 		key_size = key_info.keySize;
415 	}
416 
417 	TEE_ResetTransientObject(operation->key1);
418 	operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET;
419 
420 	if (key != TEE_HANDLE_NULL) {
421 		res = TEE_CopyObjectAttributes1(operation->key1, key);
422 		if (res != TEE_SUCCESS)
423 			goto err;
424 
425 		operation->info.handleState |= TEE_HANDLE_FLAG_KEY_SET;
426 	}
427 
428 	operation->info.keySize = key_size;
429 
430 	goto out;
431 
432 err:
433 	if (res == TEE_ERROR_CORRUPT_OBJECT ||
434 	    res == TEE_ERROR_STORAGE_NOT_AVAILABLE)
435 		return res;
436 	TEE_Panic(0);
437 out:
438 	return TEE_SUCCESS;
439 }
440 
441 TEE_Result TEE_SetOperationKey2(TEE_OperationHandle operation,
442 				TEE_ObjectHandle key1, TEE_ObjectHandle key2)
443 {
444 	TEE_Result res;
445 	uint32_t key_size = 0;
446 
447 	if (operation == TEE_HANDLE_NULL)
448 		TEE_Panic(0);
449 
450 	/* Two keys not expected */
451 	if ((operation->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) ==
452 	    0)
453 		TEE_Panic(0);
454 
455 	/* Either both keys are NULL or both are not NULL */
456 	if ((key1 == TEE_HANDLE_NULL || key2 == TEE_HANDLE_NULL) &&
457 	    key1 != key2)
458 		TEE_Panic(0);
459 
460 	if (key1 != TEE_HANDLE_NULL) {
461 		TEE_ObjectInfo key_info1;
462 		TEE_ObjectInfo key_info2;
463 
464 		res = TEE_GetObjectInfo1(key1, &key_info1);
465 		if (res != TEE_SUCCESS)
466 			goto err;
467 
468 		/* Supplied key has to meet required usage */
469 		if ((key_info1.objectUsage & operation->info.
470 		     requiredKeyUsage) != operation->info.requiredKeyUsage) {
471 			TEE_Panic(0);
472 		}
473 
474 		res = TEE_GetObjectInfo1(key2, &key_info2);
475 		if (res != TEE_SUCCESS) {
476 			if (res == TEE_ERROR_CORRUPT_OBJECT)
477 				res = TEE_ERROR_CORRUPT_OBJECT_2;
478 			goto err;
479 		}
480 
481 		/* Supplied key has to meet required usage */
482 		if ((key_info2.objectUsage & operation->info.
483 		     requiredKeyUsage) != operation->info.requiredKeyUsage) {
484 			TEE_Panic(0);
485 		}
486 
487 		/*
488 		 * AES-XTS (the only multi key algorithm supported, requires the
489 		 * keys to be of equal size.
490 		 */
491 		if (operation->info.algorithm == TEE_ALG_AES_XTS &&
492 		    key_info1.keySize != key_info2.keySize)
493 			TEE_Panic(0);
494 
495 		if (operation->info.maxKeySize < key_info1.keySize)
496 			TEE_Panic(0);
497 
498 		/*
499 		 * Odd that only the size of one key should be reported while
500 		 * size of two key are used when allocating the operation.
501 		 */
502 		key_size = key_info1.keySize;
503 	}
504 
505 	TEE_ResetTransientObject(operation->key1);
506 	TEE_ResetTransientObject(operation->key2);
507 	operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET;
508 
509 	if (key1 != TEE_HANDLE_NULL) {
510 		res = TEE_CopyObjectAttributes1(operation->key1, key1);
511 		if (res != TEE_SUCCESS)
512 			goto err;
513 
514 		res = TEE_CopyObjectAttributes1(operation->key2, key2);
515 		if (res != TEE_SUCCESS) {
516 			if (res == TEE_ERROR_CORRUPT_OBJECT)
517 				res = TEE_ERROR_CORRUPT_OBJECT_2;
518 			goto err;
519 		}
520 
521 		operation->info.handleState |= TEE_HANDLE_FLAG_KEY_SET;
522 	}
523 
524 	operation->info.keySize = key_size;
525 
526 	goto out;
527 
528 err:
529 	if (res == TEE_ERROR_CORRUPT_OBJECT ||
530 	    res == TEE_ERROR_CORRUPT_OBJECT_2 ||
531 	    res == TEE_ERROR_STORAGE_NOT_AVAILABLE ||
532 	    res == TEE_ERROR_STORAGE_NOT_AVAILABLE_2)
533 		return res;
534 	TEE_Panic(0);
535 out:
536 	return TEE_SUCCESS;
537 }
538 
539 void TEE_CopyOperation(TEE_OperationHandle dst_op, TEE_OperationHandle src_op)
540 {
541 	TEE_Result res;
542 
543 	if (dst_op == TEE_HANDLE_NULL || src_op == TEE_HANDLE_NULL)
544 		TEE_Panic(0);
545 	if (dst_op->info.algorithm != src_op->info.algorithm)
546 		TEE_Panic(0);
547 	if (src_op->info.operationClass != TEE_OPERATION_DIGEST) {
548 		TEE_ObjectHandle key1 = TEE_HANDLE_NULL;
549 		TEE_ObjectHandle key2 = TEE_HANDLE_NULL;
550 
551 		if (src_op->info.handleState & TEE_HANDLE_FLAG_KEY_SET) {
552 			key1 = src_op->key1;
553 			key2 = src_op->key2;
554 		}
555 
556 		if ((src_op->info.handleState &
557 		     TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) == 0) {
558 			TEE_SetOperationKey(dst_op, key1);
559 		} else {
560 			TEE_SetOperationKey2(dst_op, key1, key2);
561 		}
562 	}
563 	dst_op->info.handleState = src_op->info.handleState;
564 	dst_op->info.keySize = src_op->info.keySize;
565 
566 	if (dst_op->buffer_two_blocks != src_op->buffer_two_blocks ||
567 	    dst_op->block_size != src_op->block_size)
568 		TEE_Panic(0);
569 
570 	if (dst_op->buffer != NULL) {
571 		if (src_op->buffer == NULL)
572 			TEE_Panic(0);
573 
574 		memcpy(dst_op->buffer, src_op->buffer, src_op->buffer_offs);
575 		dst_op->buffer_offs = src_op->buffer_offs;
576 	} else if (src_op->buffer != NULL) {
577 		TEE_Panic(0);
578 	}
579 
580 	res = utee_cryp_state_copy(dst_op->state, src_op->state);
581 	if (res != TEE_SUCCESS)
582 		TEE_Panic(res);
583 }
584 
585 /* Cryptographic Operations API - Message Digest Functions */
586 
587 void TEE_DigestUpdate(TEE_OperationHandle operation,
588 		      void *chunk, uint32_t chunkSize)
589 {
590 	TEE_Result res = TEE_ERROR_GENERIC;
591 
592 	if (operation == TEE_HANDLE_NULL ||
593 	    operation->info.operationClass != TEE_OPERATION_DIGEST)
594 		TEE_Panic(0);
595 
596 	res = utee_hash_update(operation->state, chunk, chunkSize);
597 	if (res != TEE_SUCCESS)
598 		TEE_Panic(res);
599 }
600 
601 TEE_Result TEE_DigestDoFinal(TEE_OperationHandle operation, const void *chunk,
602 			     uint32_t chunkLen, void *hash, uint32_t *hashLen)
603 {
604 	if ((operation == TEE_HANDLE_NULL) || (!chunk && chunkLen) ||
605 	    !hash || !hashLen ||
606 	    (operation->info.operationClass != TEE_OPERATION_DIGEST))
607 		TEE_Panic(0);
608 
609 	return utee_hash_final(operation->state, chunk, chunkLen, hash,
610 			       hashLen);
611 }
612 
613 /* Cryptographic Operations API - Symmetric Cipher Functions */
614 
615 void TEE_CipherInit(TEE_OperationHandle operation, const void *IV, uint32_t IVLen)
616 {
617 	TEE_Result res;
618 
619 	if (operation == TEE_HANDLE_NULL)
620 		TEE_Panic(0);
621 	if (operation->info.operationClass != TEE_OPERATION_CIPHER)
622 		TEE_Panic(0);
623 	res = utee_cipher_init(operation->state, IV, IVLen);
624 	if (res != TEE_SUCCESS)
625 		TEE_Panic(res);
626 	operation->buffer_offs = 0;
627 	operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED;
628 }
629 
630 static TEE_Result tee_buffer_update(
631 		TEE_OperationHandle op,
632 		TEE_Result(*update_func) (uint32_t state, const void *src,
633 					  size_t slen, void *dst, uint32_t *dlen),
634 		const void *src_data, size_t src_len,
635 		void *dest_data, uint32_t *dest_len)
636 {
637 	TEE_Result res;
638 	const uint8_t *src = src_data;
639 	size_t slen = src_len;
640 	uint8_t *dst = dest_data;
641 	size_t dlen = *dest_len;
642 	size_t acc_dlen = 0;
643 	uint32_t tmp_dlen;
644 	size_t l;
645 	size_t buffer_size;
646 	size_t buffer_left;
647 
648 	if (op->buffer_two_blocks) {
649 		buffer_size = op->block_size * 2;
650 		buffer_left = 1;
651 	} else {
652 		buffer_size = op->block_size;
653 		buffer_left = 0;
654 	}
655 
656 	if (op->buffer_offs > 0) {
657 		/* Fill up complete block */
658 		if (op->buffer_offs < op->block_size)
659 			l = MIN(slen, op->block_size - op->buffer_offs);
660 		else
661 			l = MIN(slen, buffer_size - op->buffer_offs);
662 		memcpy(op->buffer + op->buffer_offs, src, l);
663 		op->buffer_offs += l;
664 		src += l;
665 		slen -= l;
666 		if ((op->buffer_offs % op->block_size) != 0)
667 			goto out;	/* Nothing left to do */
668 	}
669 
670 	/* If we can feed from buffer */
671 	if ((op->buffer_offs > 0) &&
672 	    ((op->buffer_offs + slen) >= (buffer_size + buffer_left))) {
673 		l = ROUNDUP(op->buffer_offs + slen - buffer_size,
674 				op->block_size);
675 		l = MIN(op->buffer_offs, l);
676 		tmp_dlen = dlen;
677 		res = update_func(op->state, op->buffer, l, dst, &tmp_dlen);
678 		if (res != TEE_SUCCESS)
679 			TEE_Panic(res);
680 		dst += tmp_dlen;
681 		dlen -= tmp_dlen;
682 		acc_dlen += tmp_dlen;
683 		op->buffer_offs -= l;
684 		if (op->buffer_offs > 0) {
685 			/*
686 			 * Slen is small enough to be contained in rest buffer.
687 			 */
688 			memcpy(op->buffer, op->buffer + l, buffer_size - l);
689 			memcpy(op->buffer + op->buffer_offs, src, slen);
690 			op->buffer_offs += slen;
691 			goto out;	/* Nothing left to do */
692 		}
693 	}
694 
695 	if (slen >= (buffer_size + buffer_left)) {
696 		/* Buffer is empty, feed as much as possible from src */
697 		if (TEE_ALIGNMENT_IS_OK(src, uint32_t)) {
698 			l = ROUNDUP(slen - buffer_size + 1, op->block_size);
699 
700 			tmp_dlen = dlen;
701 			res = update_func(op->state, src, l, dst, &tmp_dlen);
702 			if (res != TEE_SUCCESS)
703 				TEE_Panic(res);
704 			src += l;
705 			slen -= l;
706 			dst += tmp_dlen;
707 			dlen -= tmp_dlen;
708 			acc_dlen += tmp_dlen;
709 		} else {
710 			/*
711 			 * Supplied data isn't well aligned, we're forced to
712 			 * feed through the buffer.
713 			 */
714 			while (slen >= op->block_size) {
715 				memcpy(op->buffer, src, op->block_size);
716 
717 				tmp_dlen = dlen;
718 				res =
719 				    update_func(op->state, op->buffer,
720 						op->block_size, dst, &tmp_dlen);
721 				if (res != TEE_SUCCESS)
722 					TEE_Panic(res);
723 				src += op->block_size;
724 				slen -= op->block_size;
725 				dst += tmp_dlen;
726 				dlen -= tmp_dlen;
727 				acc_dlen += tmp_dlen;
728 			}
729 		}
730 	}
731 
732 	/* Slen is small enough to be contained in buffer. */
733 	memcpy(op->buffer + op->buffer_offs, src, slen);
734 	op->buffer_offs += slen;
735 
736 out:
737 	*dest_len = acc_dlen;
738 	return TEE_SUCCESS;
739 }
740 
741 TEE_Result TEE_CipherUpdate(TEE_OperationHandle op, const void *srcData,
742 			    uint32_t srcLen, void *destData, uint32_t *destLen)
743 {
744 	size_t req_dlen;
745 
746 	if (op == TEE_HANDLE_NULL || (srcData == NULL && srcLen != 0) ||
747 	    destLen == NULL || (destData == NULL && *destLen != 0))
748 		TEE_Panic(0);
749 	if (op->info.operationClass != TEE_OPERATION_CIPHER)
750 		TEE_Panic(0);
751 	if ((op->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0)
752 		TEE_Panic(0);
753 
754 	/* Calculate required dlen */
755 	req_dlen = ((op->buffer_offs + srcLen) / op->block_size) *
756 	    op->block_size;
757 	if (op->buffer_two_blocks) {
758 		if (req_dlen > op->block_size * 2)
759 			req_dlen -= op->block_size * 2;
760 		else
761 			req_dlen = 0;
762 	}
763 	/*
764 	 * Check that required destLen is big enough before starting to feed
765 	 * data to the algorithm. Errors during feeding of data are fatal as we
766 	 * can't restore sync with this API.
767 	 */
768 	if (*destLen < req_dlen) {
769 		*destLen = req_dlen;
770 		return TEE_ERROR_SHORT_BUFFER;
771 	}
772 
773 	tee_buffer_update(op, utee_cipher_update, srcData, srcLen, destData,
774 			  destLen);
775 
776 	return TEE_SUCCESS;
777 }
778 
779 TEE_Result TEE_CipherDoFinal(TEE_OperationHandle op,
780 			     const void *srcData, uint32_t srcLen, void *destData,
781 			     uint32_t *destLen)
782 {
783 	TEE_Result res;
784 	uint8_t *dst = destData;
785 	size_t acc_dlen = 0;
786 	uint32_t tmp_dlen;
787 	size_t req_dlen;
788 
789 	if (op == TEE_HANDLE_NULL || (srcData == NULL && srcLen != 0) ||
790 	    destLen == NULL || (destData == NULL && *destLen != 0))
791 		TEE_Panic(0);
792 	if (op->info.operationClass != TEE_OPERATION_CIPHER)
793 		TEE_Panic(0);
794 	if ((op->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0)
795 		TEE_Panic(0);
796 
797 	/*
798 	 * Check that the final block doesn't require padding for those
799 	 * algorithms that requires client to supply padding.
800 	 */
801 	if (op->info.algorithm == TEE_ALG_AES_ECB_NOPAD ||
802 	    op->info.algorithm == TEE_ALG_AES_CBC_NOPAD ||
803 	    op->info.algorithm == TEE_ALG_DES_ECB_NOPAD ||
804 	    op->info.algorithm == TEE_ALG_DES_CBC_NOPAD ||
805 	    op->info.algorithm == TEE_ALG_DES3_ECB_NOPAD ||
806 	    op->info.algorithm == TEE_ALG_DES3_CBC_NOPAD) {
807 		if (((op->buffer_offs + srcLen) % op->block_size) != 0)
808 			return TEE_ERROR_BAD_PARAMETERS;
809 	}
810 
811 	/*
812 	 * Check that required destLen is big enough before starting to feed
813 	 * data to the algorithm. Errors during feeding of data are fatal as we
814 	 * can't restore sync with this API.
815 	 */
816 	req_dlen = op->buffer_offs + srcLen;
817 	if (*destLen < req_dlen) {
818 		*destLen = req_dlen;
819 		return TEE_ERROR_SHORT_BUFFER;
820 	}
821 
822 	tmp_dlen = *destLen - acc_dlen;
823 	tee_buffer_update(op, utee_cipher_update, srcData, srcLen, dst,
824 			  &tmp_dlen);
825 	dst += tmp_dlen;
826 	acc_dlen += tmp_dlen;
827 
828 	tmp_dlen = *destLen - acc_dlen;
829 	res = utee_cipher_final(op->state, op->buffer, op->buffer_offs,
830 				dst, &tmp_dlen);
831 	if (res != TEE_SUCCESS)
832 		TEE_Panic(res);
833 	acc_dlen += tmp_dlen;
834 
835 	op->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED;
836 	*destLen = acc_dlen;
837 	return TEE_SUCCESS;
838 }
839 
840 /* Cryptographic Operations API - MAC Functions */
841 
842 void TEE_MACInit(TEE_OperationHandle operation, const void *IV, uint32_t IVLen)
843 {
844 	TEE_Result res;
845 
846 	if (operation == TEE_HANDLE_NULL)
847 		TEE_Panic(0);
848 	if (IV == NULL && IVLen != 0)
849 		TEE_Panic(0);
850 	if (operation->info.operationClass != TEE_OPERATION_MAC)
851 		TEE_Panic(0);
852 	res = utee_hash_init(operation->state, IV, IVLen);
853 	if (res != TEE_SUCCESS)
854 		TEE_Panic(res);
855 	operation->buffer_offs = 0;
856 	operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED;
857 }
858 
859 void TEE_MACUpdate(TEE_OperationHandle op, const void *chunk, uint32_t chunkSize)
860 {
861 	TEE_Result res;
862 
863 	if (op == TEE_HANDLE_NULL || (chunk == NULL && chunkSize != 0))
864 		TEE_Panic(0);
865 	if (op->info.operationClass != TEE_OPERATION_MAC)
866 		TEE_Panic(0);
867 	if ((op->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0)
868 		TEE_Panic(0);
869 
870 	res = utee_hash_update(op->state, chunk, chunkSize);
871 	if (res != TEE_SUCCESS)
872 		TEE_Panic(res);
873 }
874 
875 TEE_Result TEE_MACComputeFinal(TEE_OperationHandle op,
876 			       const void *message, uint32_t messageLen,
877 			       void *mac, uint32_t *macLen)
878 {
879 	TEE_Result res;
880 
881 	if (op == TEE_HANDLE_NULL || (message == NULL && messageLen != 0) ||
882 	    mac == NULL || macLen == NULL)
883 		TEE_Panic(0);
884 	if (op->info.operationClass != TEE_OPERATION_MAC)
885 		TEE_Panic(0);
886 	if ((op->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0)
887 		TEE_Panic(0);
888 
889 	res = utee_hash_final(op->state, message, messageLen, mac, macLen);
890 	op->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED;
891 	return res;
892 }
893 
894 TEE_Result TEE_MACCompareFinal(TEE_OperationHandle operation,
895 			       const void *message, uint32_t messageLen,
896 			       const void *mac, uint32_t macLen)
897 {
898 	TEE_Result res;
899 	uint8_t computed_mac[TEE_MAX_HASH_SIZE];
900 	uint32_t computed_mac_size = TEE_MAX_HASH_SIZE;
901 
902 	res = TEE_MACComputeFinal(operation, message, messageLen, computed_mac,
903 				  &computed_mac_size);
904 	if (res != TEE_SUCCESS)
905 		return res;
906 	if (computed_mac_size != macLen)
907 		return TEE_ERROR_MAC_INVALID;
908 	if (buf_compare_ct(mac, computed_mac, computed_mac_size) != 0)
909 		return TEE_ERROR_MAC_INVALID;
910 	return TEE_SUCCESS;
911 }
912 
913 /* Cryptographic Operations API - Authenticated Encryption Functions */
914 
915 TEE_Result TEE_AEInit(TEE_OperationHandle op, const void *nonce,
916 		      uint32_t nonceLen, uint32_t tagLen, uint32_t AADLen,
917 		      uint32_t payloadLen)
918 {
919 	TEE_Result res;
920 
921 	if (op == TEE_HANDLE_NULL || nonce == NULL)
922 		TEE_Panic(0);
923 	if (op->info.operationClass != TEE_OPERATION_AE)
924 		TEE_Panic(0);
925 
926 	/*
927 	 * AES-CCM tag len is specified by AES-CCM spec and handled in TEE Core
928 	 * in the implementation. But AES-GCM spec doesn't specify the tag len
929 	 * according to the same principle so we have to check here instead to
930 	 * be GP compliant.
931 	 */
932 	if (op->info.algorithm == TEE_ALG_AES_GCM) {
933 		/*
934 		 * From GP spec: For AES-GCM, can be 128, 120, 112, 104, or 96
935 		 */
936 		if (tagLen < 96 || tagLen > 128 || (tagLen % 8 != 0))
937 			return TEE_ERROR_NOT_SUPPORTED;
938 	}
939 
940 	res = utee_authenc_init(op->state, nonce, nonceLen, tagLen / 8, AADLen,
941 				payloadLen);
942 	if (res != TEE_SUCCESS) {
943 		if (res != TEE_ERROR_NOT_SUPPORTED)
944 			TEE_Panic(res);
945 		return res;
946 	}
947 	op->ae_tag_len = tagLen / 8;
948 
949 	op->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED;
950 	return TEE_SUCCESS;
951 }
952 
953 void TEE_AEUpdateAAD(TEE_OperationHandle op, const void *AADdata,
954 		     uint32_t AADdataLen)
955 {
956 	TEE_Result res;
957 
958 	if (op == TEE_HANDLE_NULL || (AADdata == NULL && AADdataLen != 0))
959 		TEE_Panic(0);
960 	if (op->info.operationClass != TEE_OPERATION_AE)
961 		TEE_Panic(0);
962 	if ((op->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0)
963 		TEE_Panic(0);
964 
965 	res = utee_authenc_update_aad(op->state, AADdata, AADdataLen);
966 	if (res != TEE_SUCCESS)
967 		TEE_Panic(res);
968 }
969 
970 TEE_Result TEE_AEUpdate(TEE_OperationHandle op, const void *srcData,
971 			uint32_t srcLen, void *destData, uint32_t *destLen)
972 {
973 	size_t req_dlen;
974 
975 	if (op == TEE_HANDLE_NULL || (srcData == NULL && srcLen != 0) ||
976 	    destLen == NULL || (destData == NULL && *destLen != 0))
977 		TEE_Panic(0);
978 	if (op->info.operationClass != TEE_OPERATION_AE)
979 		TEE_Panic(0);
980 	if ((op->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0)
981 		TEE_Panic(0);
982 
983 	/*
984 	 * Check that required destLen is big enough before starting to feed
985 	 * data to the algorithm. Errors during feeding of data are fatal as we
986 	 * can't restore sync with this API.
987 	 */
988 	req_dlen = ROUNDDOWN(op->buffer_offs + srcLen, op->block_size);
989 	if (*destLen < req_dlen) {
990 		*destLen = req_dlen;
991 		return TEE_ERROR_SHORT_BUFFER;
992 	}
993 
994 	tee_buffer_update(op, utee_authenc_update_payload, srcData, srcLen,
995 			  destData, destLen);
996 
997 	return TEE_SUCCESS;
998 }
999 
1000 TEE_Result TEE_AEEncryptFinal(TEE_OperationHandle op,
1001 			      const void *srcData, uint32_t srcLen,
1002 			      void *destData, uint32_t *destLen, void *tag,
1003 			      uint32_t *tagLen)
1004 {
1005 	TEE_Result res;
1006 	uint8_t *dst = destData;
1007 	size_t acc_dlen = 0;
1008 	uint32_t tmp_dlen;
1009 	size_t req_dlen;
1010 
1011 	if (op == TEE_HANDLE_NULL || (srcData == NULL && srcLen != 0) ||
1012 	    destLen == NULL || (destData == NULL && *destLen != 0) ||
1013 	    tag == NULL || tagLen == NULL)
1014 		TEE_Panic(0);
1015 	if (op->info.operationClass != TEE_OPERATION_AE)
1016 		TEE_Panic(0);
1017 	if ((op->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0)
1018 		TEE_Panic(0);
1019 
1020 	/*
1021 	 * Check that required destLen is big enough before starting to feed
1022 	 * data to the algorithm. Errors during feeding of data are fatal as we
1023 	 * can't restore sync with this API.
1024 	 */
1025 	req_dlen = op->buffer_offs + srcLen;
1026 	if (*destLen < req_dlen) {
1027 		*destLen = req_dlen;
1028 		return TEE_ERROR_SHORT_BUFFER;
1029 	}
1030 
1031 	/*
1032 	 * Need to check this before update_payload since sync would be lost if
1033 	 * we return short buffer after that.
1034 	 */
1035 	if (*tagLen < op->ae_tag_len) {
1036 		*tagLen = op->ae_tag_len;
1037 		return TEE_ERROR_SHORT_BUFFER;
1038 	}
1039 
1040 	tmp_dlen = *destLen - acc_dlen;
1041 	tee_buffer_update(op, utee_authenc_update_payload, srcData, srcLen,
1042 			  dst, &tmp_dlen);
1043 	dst += tmp_dlen;
1044 	acc_dlen += tmp_dlen;
1045 
1046 	tmp_dlen = *destLen - acc_dlen;
1047 	res =
1048 	    utee_authenc_enc_final(op->state, op->buffer, op->buffer_offs, dst,
1049 				   &tmp_dlen, tag, tagLen);
1050 	if (res != TEE_SUCCESS)
1051 		TEE_Panic(res);
1052 	acc_dlen += tmp_dlen;
1053 
1054 	*destLen = acc_dlen;
1055 	op->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED;
1056 
1057 	return res;
1058 }
1059 
1060 TEE_Result TEE_AEDecryptFinal(TEE_OperationHandle op,
1061 			      const void *srcData, uint32_t srcLen,
1062 			      void *destData, uint32_t *destLen, const void *tag,
1063 			      uint32_t tagLen)
1064 {
1065 	TEE_Result res;
1066 	uint8_t *dst = destData;
1067 	size_t acc_dlen = 0;
1068 	uint32_t tmp_dlen;
1069 	size_t req_dlen;
1070 
1071 	if (op == TEE_HANDLE_NULL || (srcData == NULL && srcLen != 0) ||
1072 	    destLen == NULL || (destData == NULL && *destLen != 0) ||
1073 	    (tag == NULL && tagLen != 0))
1074 		TEE_Panic(0);
1075 	if (op->info.operationClass != TEE_OPERATION_AE)
1076 		TEE_Panic(0);
1077 	if ((op->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0)
1078 		TEE_Panic(0);
1079 
1080 	/*
1081 	 * Check that required destLen is big enough before starting to feed
1082 	 * data to the algorithm. Errors during feeding of data are fatal as we
1083 	 * can't restore sync with this API.
1084 	 */
1085 	req_dlen = op->buffer_offs + srcLen;
1086 	if (*destLen < req_dlen) {
1087 		*destLen = req_dlen;
1088 		return TEE_ERROR_SHORT_BUFFER;
1089 	}
1090 
1091 	tmp_dlen = *destLen - acc_dlen;
1092 	tee_buffer_update(op, utee_authenc_update_payload, srcData, srcLen,
1093 			  dst, &tmp_dlen);
1094 	dst += tmp_dlen;
1095 	acc_dlen += tmp_dlen;
1096 
1097 	tmp_dlen = *destLen - acc_dlen;
1098 	res =
1099 	    utee_authenc_dec_final(op->state, op->buffer, op->buffer_offs, dst,
1100 				   &tmp_dlen, tag, tagLen);
1101 	if (res != TEE_SUCCESS && res != TEE_ERROR_MAC_INVALID)
1102 		TEE_Panic(res);
1103 	/* Supplied tagLen should match what we initiated with */
1104 	if (tagLen != op->ae_tag_len)
1105 		res = TEE_ERROR_MAC_INVALID;
1106 
1107 	acc_dlen += tmp_dlen;
1108 
1109 	*destLen = acc_dlen;
1110 	op->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED;
1111 
1112 	return res;
1113 }
1114 
1115 /* Cryptographic Operations API - Asymmetric Functions */
1116 
1117 TEE_Result TEE_AsymmetricEncrypt(TEE_OperationHandle op,
1118 				 const TEE_Attribute *params,
1119 				 uint32_t paramCount, const void *srcData,
1120 				 uint32_t srcLen, void *destData,
1121 				 uint32_t *destLen)
1122 {
1123 	TEE_Result res;
1124 
1125 	if (op == TEE_HANDLE_NULL || (srcData == NULL && srcLen != 0) ||
1126 	    destLen == NULL || (destData == NULL && *destLen != 0))
1127 		TEE_Panic(0);
1128 	if (paramCount != 0 && params == NULL)
1129 		TEE_Panic(0);
1130 	if (op->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER)
1131 		TEE_Panic(0);
1132 	if (op->info.mode != TEE_MODE_ENCRYPT)
1133 		TEE_Panic(0);
1134 
1135 	res = utee_asymm_operate(op->state, params, paramCount, srcData, srcLen,
1136 				 destData, destLen);
1137 	if (res != TEE_SUCCESS &&
1138 	    res != TEE_ERROR_SHORT_BUFFER &&
1139 	    res != TEE_ERROR_BAD_PARAMETERS)
1140 		TEE_Panic(res);
1141 	return res;
1142 }
1143 
1144 TEE_Result TEE_AsymmetricDecrypt(TEE_OperationHandle op,
1145 				 const TEE_Attribute *params,
1146 				 uint32_t paramCount, const void *srcData,
1147 				 uint32_t srcLen, void *destData,
1148 				 uint32_t *destLen)
1149 {
1150 	TEE_Result res;
1151 
1152 	if (op == TEE_HANDLE_NULL || (srcData == NULL && srcLen != 0) ||
1153 	    destLen == NULL || (destData == NULL && *destLen != 0))
1154 		TEE_Panic(0);
1155 	if (paramCount != 0 && params == NULL)
1156 		TEE_Panic(0);
1157 	if (op->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER)
1158 		TEE_Panic(0);
1159 	if (op->info.mode != TEE_MODE_DECRYPT)
1160 		TEE_Panic(0);
1161 
1162 	res = utee_asymm_operate(op->state, params, paramCount, srcData, srcLen,
1163 				 destData, destLen);
1164 	if (res != TEE_SUCCESS &&
1165 	    res != TEE_ERROR_SHORT_BUFFER &&
1166 	    res != TEE_ERROR_BAD_PARAMETERS)
1167 		TEE_Panic(res);
1168 	return res;
1169 }
1170 
1171 TEE_Result TEE_AsymmetricSignDigest(TEE_OperationHandle op,
1172 				    const TEE_Attribute *params,
1173 				    uint32_t paramCount, const void *digest,
1174 				    uint32_t digestLen, void *signature,
1175 				    uint32_t *signatureLen)
1176 {
1177 	TEE_Result res;
1178 
1179 	if (op == TEE_HANDLE_NULL || (digest == NULL && digestLen != 0) ||
1180 	    signature == NULL || signatureLen == NULL)
1181 		TEE_Panic(0);
1182 	if (paramCount != 0 && params == NULL)
1183 		TEE_Panic(0);
1184 	if (op->info.operationClass != TEE_OPERATION_ASYMMETRIC_SIGNATURE)
1185 		TEE_Panic(0);
1186 	if (op->info.mode != TEE_MODE_SIGN)
1187 		TEE_Panic(0);
1188 
1189 	res =
1190 	    utee_asymm_operate(op->state, params, paramCount, digest, digestLen,
1191 			       signature, signatureLen);
1192 	if (res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER)
1193 		TEE_Panic(res);
1194 	return res;
1195 }
1196 
1197 TEE_Result TEE_AsymmetricVerifyDigest(TEE_OperationHandle op,
1198 				      const TEE_Attribute *params,
1199 				      uint32_t paramCount, const void *digest,
1200 				      uint32_t digestLen, const void *signature,
1201 				      uint32_t signatureLen)
1202 {
1203 	TEE_Result res;
1204 
1205 	if (op == TEE_HANDLE_NULL || (digest == NULL && digestLen != 0) ||
1206 	    (signature == NULL && signatureLen != 0))
1207 		TEE_Panic(0);
1208 	if (paramCount != 0 && params == NULL)
1209 		TEE_Panic(0);
1210 	if (op->info.operationClass != TEE_OPERATION_ASYMMETRIC_SIGNATURE)
1211 		TEE_Panic(0);
1212 	if (op->info.mode != TEE_MODE_VERIFY)
1213 		TEE_Panic(0);
1214 
1215 	res =
1216 	    utee_asymm_verify(op->state, params, paramCount, digest, digestLen,
1217 			      signature, signatureLen);
1218 	if (res != TEE_SUCCESS && res != TEE_ERROR_SIGNATURE_INVALID)
1219 		TEE_Panic(res);
1220 	return res;
1221 }
1222 
1223 /* Cryptographic Operations API - Key Derivation Functions */
1224 
1225 void TEE_DeriveKey(TEE_OperationHandle operation,
1226 		   const TEE_Attribute *params, uint32_t paramCount,
1227 		   TEE_ObjectHandle derivedKey)
1228 {
1229 	TEE_Result res;
1230 	TEE_ObjectInfo key_info;
1231 
1232 	if (operation == TEE_HANDLE_NULL || derivedKey == 0)
1233 		TEE_Panic(0);
1234 	if (paramCount != 0 && params == NULL)
1235 		TEE_Panic(0);
1236 	if (TEE_ALG_GET_CLASS(operation->info.algorithm) !=
1237 			TEE_OPERATION_KEY_DERIVATION)
1238 		TEE_Panic(0);
1239 
1240 	if (operation->info.operationClass != TEE_OPERATION_KEY_DERIVATION)
1241 		TEE_Panic(0);
1242 	if (operation->info.mode != TEE_MODE_DERIVE)
1243 		TEE_Panic(0);
1244 	if ((operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET) == 0)
1245 		TEE_Panic(0);
1246 
1247 	res = utee_cryp_obj_get_info((uint32_t) derivedKey, &key_info);
1248 	if (res != TEE_SUCCESS)
1249 		TEE_Panic(0);
1250 
1251 	if (key_info.objectType != TEE_TYPE_GENERIC_SECRET)
1252 		TEE_Panic(0);
1253 	if ((key_info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) != 0)
1254 		TEE_Panic(0);
1255 
1256 	res = utee_cryp_derive_key(operation->state, params, paramCount,
1257 				   (uint32_t) derivedKey);
1258 	if (res != TEE_SUCCESS)
1259 		TEE_Panic(res);
1260 }
1261 
1262 /* Cryptographic Operations API - Random Number Generation Functions */
1263 
1264 void TEE_GenerateRandom(void *randomBuffer, uint32_t randomBufferLen)
1265 {
1266 	TEE_Result res;
1267 
1268 	res = utee_cryp_random_number_generate(randomBuffer, randomBufferLen);
1269 	if (res != TEE_SUCCESS)
1270 		TEE_Panic(res);
1271 }
1272