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