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