xref: /optee_os/core/lib/libtomcrypt/rsa.c (revision 5b25c76ac40f830867e3d60800120ffd7874e8dc)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2014-2019, Linaro Limited
4  */
5 
6 #include <crypto/crypto.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <tee_api_types.h>
10 #include <tee_api_defines_extensions.h>
11 #include <tee/tee_cryp_utl.h>
12 #include <trace.h>
13 #include <utee_defines.h>
14 
15 #include "acipher_helpers.h"
16 
17 
18 /*
19  * Compute the LibTomCrypt "hashindex" given a TEE Algorithm "algo"
20  * Return
21  * - TEE_SUCCESS in case of success,
22  * - TEE_ERROR_BAD_PARAMETERS in case algo is not a valid algo
23  * - TEE_ERROR_NOT_SUPPORTED in case algo is not supported by LTC
24  * Return -1 in case of error
25  */
26 static TEE_Result tee_algo_to_ltc_hashindex(uint32_t algo, int *ltc_hashindex)
27 {
28 	switch (algo) {
29 #if defined(_CFG_CORE_LTC_SHA1)
30 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1:
31 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1:
32 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1:
33 		*ltc_hashindex = find_hash("sha1");
34 		break;
35 #endif
36 #if defined(_CFG_CORE_LTC_MD5)
37 	case TEE_ALG_RSASSA_PKCS1_V1_5_MD5:
38 		*ltc_hashindex = find_hash("md5");
39 		break;
40 #endif
41 #if defined(_CFG_CORE_LTC_SHA224)
42 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224:
43 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224:
44 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224:
45 		*ltc_hashindex = find_hash("sha224");
46 		break;
47 #endif
48 #if defined(_CFG_CORE_LTC_SHA256)
49 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256:
50 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256:
51 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256:
52 		*ltc_hashindex = find_hash("sha256");
53 		break;
54 #endif
55 #if defined(_CFG_CORE_LTC_SHA384)
56 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384:
57 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384:
58 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384:
59 		*ltc_hashindex = find_hash("sha384");
60 		break;
61 #endif
62 #if defined(_CFG_CORE_LTC_SHA512)
63 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512:
64 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512:
65 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512:
66 		*ltc_hashindex = find_hash("sha512");
67 		break;
68 #endif
69 	case TEE_ALG_RSASSA_PKCS1_V1_5:
70 	case TEE_ALG_RSAES_PKCS1_V1_5:
71 		/* invalid one. but it should not be used anyway */
72 		*ltc_hashindex = -1;
73 		return TEE_SUCCESS;
74 
75 	default:
76 		return TEE_ERROR_BAD_PARAMETERS;
77 	}
78 
79 	if (*ltc_hashindex < 0)
80 		return TEE_ERROR_NOT_SUPPORTED;
81 	else
82 		return TEE_SUCCESS;
83 }
84 
85 TEE_Result crypto_acipher_alloc_rsa_keypair(struct rsa_keypair *s,
86 					    size_t key_size_bits __unused)
87 {
88 	memset(s, 0, sizeof(*s));
89 	if (!bn_alloc_max(&s->e))
90 		return TEE_ERROR_OUT_OF_MEMORY;
91 	if (!bn_alloc_max(&s->d))
92 		goto err;
93 	if (!bn_alloc_max(&s->n))
94 		goto err;
95 	if (!bn_alloc_max(&s->p))
96 		goto err;
97 	if (!bn_alloc_max(&s->q))
98 		goto err;
99 	if (!bn_alloc_max(&s->qp))
100 		goto err;
101 	if (!bn_alloc_max(&s->dp))
102 		goto err;
103 	if (!bn_alloc_max(&s->dq))
104 		goto err;
105 
106 	return TEE_SUCCESS;
107 err:
108 	crypto_bignum_free(s->e);
109 	crypto_bignum_free(s->d);
110 	crypto_bignum_free(s->n);
111 	crypto_bignum_free(s->p);
112 	crypto_bignum_free(s->q);
113 	crypto_bignum_free(s->qp);
114 	crypto_bignum_free(s->dp);
115 
116 	return TEE_ERROR_OUT_OF_MEMORY;
117 }
118 
119 TEE_Result crypto_acipher_alloc_rsa_public_key(struct rsa_public_key *s,
120 					       size_t key_size_bits __unused)
121 {
122 	memset(s, 0, sizeof(*s));
123 	if (!bn_alloc_max(&s->e))
124 		return TEE_ERROR_OUT_OF_MEMORY;
125 	if (!bn_alloc_max(&s->n))
126 		goto err;
127 	return TEE_SUCCESS;
128 err:
129 	crypto_bignum_free(s->e);
130 	return TEE_ERROR_OUT_OF_MEMORY;
131 }
132 
133 void crypto_acipher_free_rsa_public_key(struct rsa_public_key *s)
134 {
135 	if (!s)
136 		return;
137 	crypto_bignum_free(s->n);
138 	crypto_bignum_free(s->e);
139 }
140 
141 TEE_Result crypto_acipher_gen_rsa_key(struct rsa_keypair *key, size_t key_size)
142 {
143 	TEE_Result res;
144 	rsa_key ltc_tmp_key;
145 	int ltc_res;
146 	long e;
147 
148 	/* get the public exponent */
149 	e = mp_get_int(key->e);
150 
151 	/* Generate a temporary RSA key */
152 	ltc_res = rsa_make_key(NULL, find_prng("prng_crypto"), key_size / 8, e,
153 			       &ltc_tmp_key);
154 	if (ltc_res != CRYPT_OK) {
155 		res = TEE_ERROR_BAD_PARAMETERS;
156 	} else if ((size_t)mp_count_bits(ltc_tmp_key.N) != key_size) {
157 		rsa_free(&ltc_tmp_key);
158 		res = TEE_ERROR_BAD_PARAMETERS;
159 	} else {
160 		/* Copy the key */
161 		ltc_mp.copy(ltc_tmp_key.e,  key->e);
162 		ltc_mp.copy(ltc_tmp_key.d,  key->d);
163 		ltc_mp.copy(ltc_tmp_key.N,  key->n);
164 		ltc_mp.copy(ltc_tmp_key.p,  key->p);
165 		ltc_mp.copy(ltc_tmp_key.q,  key->q);
166 		ltc_mp.copy(ltc_tmp_key.qP, key->qp);
167 		ltc_mp.copy(ltc_tmp_key.dP, key->dp);
168 		ltc_mp.copy(ltc_tmp_key.dQ, key->dq);
169 
170 		/* Free the temporary key */
171 		rsa_free(&ltc_tmp_key);
172 		res = TEE_SUCCESS;
173 	}
174 
175 	return res;
176 }
177 
178 static TEE_Result rsadorep(rsa_key *ltc_key, const uint8_t *src,
179 			   size_t src_len, uint8_t *dst, size_t *dst_len)
180 {
181 	TEE_Result res = TEE_SUCCESS;
182 	uint8_t *buf = NULL;
183 	unsigned long blen, offset;
184 	int ltc_res;
185 
186 	/*
187 	 * Use a temporary buffer since we don't know exactly how large the
188 	 * required size of the out buffer without doing a partial decrypt.
189 	 * We know the upper bound though.
190 	 */
191 	blen = _CFG_CORE_LTC_BIGNUM_MAX_BITS / sizeof(uint8_t);
192 	buf = malloc(blen);
193 	if (!buf) {
194 		res = TEE_ERROR_OUT_OF_MEMORY;
195 		goto out;
196 	}
197 
198 	ltc_res = rsa_exptmod(src, src_len, buf, &blen, ltc_key->type,
199 			      ltc_key);
200 	switch (ltc_res) {
201 	case CRYPT_PK_NOT_PRIVATE:
202 	case CRYPT_PK_INVALID_TYPE:
203 	case CRYPT_PK_INVALID_SIZE:
204 	case CRYPT_INVALID_PACKET:
205 		EMSG("rsa_exptmod() returned %d", ltc_res);
206 		res = TEE_ERROR_BAD_PARAMETERS;
207 		goto out;
208 	case CRYPT_OK:
209 		break;
210 	default:
211 		/* This will result in a panic */
212 		EMSG("rsa_exptmod() returned %d", ltc_res);
213 		res = TEE_ERROR_GENERIC;
214 		goto out;
215 	}
216 
217 	/* Remove the zero-padding (leave one zero if buff is all zeroes) */
218 	offset = 0;
219 	while ((offset < blen - 1) && (buf[offset] == 0))
220 		offset++;
221 
222 	if (*dst_len < blen - offset) {
223 		*dst_len = blen - offset;
224 		res = TEE_ERROR_SHORT_BUFFER;
225 		goto out;
226 	}
227 
228 	res = TEE_SUCCESS;
229 	*dst_len = blen - offset;
230 	memcpy(dst, (char *)buf + offset, *dst_len);
231 
232 out:
233 	if (buf)
234 		free(buf);
235 
236 	return res;
237 }
238 
239 TEE_Result crypto_acipher_rsanopad_encrypt(struct rsa_public_key *key,
240 					   const uint8_t *src, size_t src_len,
241 					   uint8_t *dst, size_t *dst_len)
242 {
243 	TEE_Result res;
244 	rsa_key ltc_key = { 0, };
245 
246 	ltc_key.type = PK_PUBLIC;
247 	ltc_key.e = key->e;
248 	ltc_key.N = key->n;
249 
250 	res = rsadorep(&ltc_key, src, src_len, dst, dst_len);
251 	return res;
252 }
253 
254 TEE_Result crypto_acipher_rsanopad_decrypt(struct rsa_keypair *key,
255 					   const uint8_t *src, size_t src_len,
256 					   uint8_t *dst, size_t *dst_len)
257 {
258 	TEE_Result res;
259 	rsa_key ltc_key = { 0, };
260 
261 	ltc_key.type = PK_PRIVATE;
262 	ltc_key.e = key->e;
263 	ltc_key.N = key->n;
264 	ltc_key.d = key->d;
265 	if (key->p && crypto_bignum_num_bytes(key->p)) {
266 		ltc_key.p = key->p;
267 		ltc_key.q = key->q;
268 		ltc_key.qP = key->qp;
269 		ltc_key.dP = key->dp;
270 		ltc_key.dQ = key->dq;
271 	}
272 
273 	res = rsadorep(&ltc_key, src, src_len, dst, dst_len);
274 	return res;
275 }
276 
277 TEE_Result crypto_acipher_rsaes_decrypt(uint32_t algo, struct rsa_keypair *key,
278 					const uint8_t *label, size_t label_len,
279 					const uint8_t *src, size_t src_len,
280 					uint8_t *dst, size_t *dst_len)
281 {
282 	TEE_Result res = TEE_SUCCESS;
283 	void *buf = NULL;
284 	unsigned long blen;
285 	int ltc_hashindex, ltc_res, ltc_stat, ltc_rsa_algo;
286 	size_t mod_size;
287 	rsa_key ltc_key = { 0, };
288 
289 	ltc_key.type = PK_PRIVATE;
290 	ltc_key.e = key->e;
291 	ltc_key.d = key->d;
292 	ltc_key.N = key->n;
293 	if (key->p && crypto_bignum_num_bytes(key->p)) {
294 		ltc_key.p = key->p;
295 		ltc_key.q = key->q;
296 		ltc_key.qP = key->qp;
297 		ltc_key.dP = key->dp;
298 		ltc_key.dQ = key->dq;
299 	}
300 
301 	/* Get the algorithm */
302 	res = tee_algo_to_ltc_hashindex(algo, &ltc_hashindex);
303 	if (res != TEE_SUCCESS) {
304 		EMSG("tee_algo_to_ltc_hashindex() returned %d", (int)res);
305 		goto out;
306 	}
307 
308 	/*
309 	 * Use a temporary buffer since we don't know exactly how large
310 	 * the required size of the out buffer without doing a partial
311 	 * decrypt. We know the upper bound though.
312 	 */
313 	if (algo == TEE_ALG_RSAES_PKCS1_V1_5) {
314 		mod_size = ltc_mp.unsigned_size((void *)(ltc_key.N));
315 		blen = mod_size - 11;
316 		ltc_rsa_algo = LTC_PKCS_1_V1_5;
317 	} else {
318 		/* Decoded message is always shorter than encrypted message */
319 		blen = src_len;
320 		ltc_rsa_algo = LTC_PKCS_1_OAEP;
321 	}
322 
323 	buf = malloc(blen);
324 	if (!buf) {
325 		res = TEE_ERROR_OUT_OF_MEMORY;
326 		goto out;
327 	}
328 
329 	ltc_res = rsa_decrypt_key_ex(src, src_len, buf, &blen,
330 				     ((label_len == 0) ? 0 : label), label_len,
331 				     ltc_hashindex, ltc_rsa_algo, &ltc_stat,
332 				     &ltc_key);
333 	switch (ltc_res) {
334 	case CRYPT_PK_INVALID_PADDING:
335 	case CRYPT_INVALID_PACKET:
336 	case CRYPT_PK_INVALID_SIZE:
337 		EMSG("rsa_decrypt_key_ex() returned %d", ltc_res);
338 		res = TEE_ERROR_BAD_PARAMETERS;
339 		goto out;
340 	case CRYPT_OK:
341 		break;
342 	default:
343 		/* This will result in a panic */
344 		EMSG("rsa_decrypt_key_ex() returned %d", ltc_res);
345 		res = TEE_ERROR_GENERIC;
346 		goto out;
347 	}
348 	if (ltc_stat != 1) {
349 		/* This will result in a panic */
350 		EMSG("rsa_decrypt_key_ex() returned %d and %d",
351 		     ltc_res, ltc_stat);
352 		res = TEE_ERROR_GENERIC;
353 		goto out;
354 	}
355 
356 	if (*dst_len < blen) {
357 		*dst_len = blen;
358 		res = TEE_ERROR_SHORT_BUFFER;
359 		goto out;
360 	}
361 
362 	res = TEE_SUCCESS;
363 	*dst_len = blen;
364 	memcpy(dst, buf, blen);
365 
366 out:
367 	if (buf)
368 		free(buf);
369 
370 	return res;
371 }
372 
373 TEE_Result crypto_acipher_rsaes_encrypt(uint32_t algo,
374 					struct rsa_public_key *key,
375 					const uint8_t *label, size_t label_len,
376 					const uint8_t *src, size_t src_len,
377 					uint8_t *dst, size_t *dst_len)
378 {
379 	TEE_Result res;
380 	uint32_t mod_size;
381 	int ltc_hashindex, ltc_res, ltc_rsa_algo;
382 	rsa_key ltc_key = {
383 		.type = PK_PUBLIC,
384 		.e = key->e,
385 		.N = key->n
386 	};
387 
388 	mod_size =  ltc_mp.unsigned_size((void *)(ltc_key.N));
389 	if (*dst_len < mod_size) {
390 		*dst_len = mod_size;
391 		res = TEE_ERROR_SHORT_BUFFER;
392 		goto out;
393 	}
394 	*dst_len = mod_size;
395 
396 	/* Get the algorithm */
397 	res = tee_algo_to_ltc_hashindex(algo, &ltc_hashindex);
398 	if (res != TEE_SUCCESS)
399 		goto out;
400 
401 	if (algo == TEE_ALG_RSAES_PKCS1_V1_5)
402 		ltc_rsa_algo = LTC_PKCS_1_V1_5;
403 	else
404 		ltc_rsa_algo = LTC_PKCS_1_OAEP;
405 
406 	ltc_res = rsa_encrypt_key_ex(src, src_len, dst,
407 				     (unsigned long *)(dst_len), label,
408 				     label_len, NULL, find_prng("prng_crypto"),
409 				     ltc_hashindex, ltc_rsa_algo, &ltc_key);
410 	switch (ltc_res) {
411 	case CRYPT_PK_INVALID_PADDING:
412 	case CRYPT_INVALID_PACKET:
413 	case CRYPT_PK_INVALID_SIZE:
414 		EMSG("rsa_encrypt_key_ex() returned %d", ltc_res);
415 		res = TEE_ERROR_BAD_PARAMETERS;
416 		goto out;
417 	case CRYPT_OK:
418 		break;
419 	default:
420 		/* This will result in a panic */
421 		res = TEE_ERROR_GENERIC;
422 		goto out;
423 	}
424 	res = TEE_SUCCESS;
425 
426 out:
427 	return res;
428 }
429 
430 TEE_Result crypto_acipher_rsassa_sign(uint32_t algo, struct rsa_keypair *key,
431 				      int salt_len, const uint8_t *msg,
432 				      size_t msg_len, uint8_t *sig,
433 				      size_t *sig_len)
434 {
435 	TEE_Result res;
436 	size_t hash_size, mod_size;
437 	int ltc_res, ltc_rsa_algo, ltc_hashindex;
438 	unsigned long ltc_sig_len;
439 	rsa_key ltc_key = { 0, };
440 
441 	ltc_key.type = PK_PRIVATE;
442 	ltc_key.e = key->e;
443 	ltc_key.N = key->n;
444 	ltc_key.d = key->d;
445 	if (key->p && crypto_bignum_num_bytes(key->p)) {
446 		ltc_key.p = key->p;
447 		ltc_key.q = key->q;
448 		ltc_key.qP = key->qp;
449 		ltc_key.dP = key->dp;
450 		ltc_key.dQ = key->dq;
451 	}
452 
453 	switch (algo) {
454 	case TEE_ALG_RSASSA_PKCS1_V1_5:
455 		ltc_rsa_algo = LTC_PKCS_1_V1_5_NA1;
456 		break;
457 	case TEE_ALG_RSASSA_PKCS1_V1_5_MD5:
458 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1:
459 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224:
460 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256:
461 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384:
462 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512:
463 		ltc_rsa_algo = LTC_PKCS_1_V1_5;
464 		break;
465 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1:
466 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224:
467 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256:
468 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384:
469 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512:
470 		ltc_rsa_algo = LTC_PKCS_1_PSS;
471 		break;
472 	default:
473 		res = TEE_ERROR_BAD_PARAMETERS;
474 		goto err;
475 	}
476 
477 	if (ltc_rsa_algo != LTC_PKCS_1_V1_5_NA1) {
478 		ltc_res = tee_algo_to_ltc_hashindex(algo, &ltc_hashindex);
479 		if (ltc_res != CRYPT_OK) {
480 			res = TEE_ERROR_BAD_PARAMETERS;
481 			goto err;
482 		}
483 
484 		res = tee_alg_get_digest_size(TEE_DIGEST_HASH_TO_ALGO(algo),
485 					      &hash_size);
486 		if (res != TEE_SUCCESS)
487 			goto err;
488 
489 		if (msg_len != hash_size) {
490 			res = TEE_ERROR_BAD_PARAMETERS;
491 			goto err;
492 		}
493 	}
494 
495 	mod_size = ltc_mp.unsigned_size((void *)(ltc_key.N));
496 
497 	if (*sig_len < mod_size) {
498 		*sig_len = mod_size;
499 		res = TEE_ERROR_SHORT_BUFFER;
500 		goto err;
501 	}
502 
503 	ltc_sig_len = mod_size;
504 
505 	ltc_res = rsa_sign_hash_ex(msg, msg_len, sig, &ltc_sig_len,
506 				   ltc_rsa_algo, NULL, find_prng("prng_crypto"),
507 				   ltc_hashindex, salt_len, &ltc_key);
508 
509 	*sig_len = ltc_sig_len;
510 
511 	if (ltc_res != CRYPT_OK) {
512 		res = TEE_ERROR_BAD_PARAMETERS;
513 		goto err;
514 	}
515 	res = TEE_SUCCESS;
516 
517 err:
518 	return res;
519 }
520 
521 TEE_Result crypto_acipher_rsassa_verify(uint32_t algo,
522 					struct rsa_public_key *key,
523 					int salt_len, const uint8_t *msg,
524 					size_t msg_len, const uint8_t *sig,
525 					size_t sig_len)
526 {
527 	TEE_Result res;
528 	uint32_t bigint_size;
529 	size_t hash_size;
530 	int stat, ltc_hashindex, ltc_res, ltc_rsa_algo;
531 	rsa_key ltc_key = {
532 		.type = PK_PUBLIC,
533 		.e = key->e,
534 		.N = key->n
535 	};
536 
537 	if (algo != TEE_ALG_RSASSA_PKCS1_V1_5) {
538 		res = tee_alg_get_digest_size(TEE_DIGEST_HASH_TO_ALGO(algo),
539 					      &hash_size);
540 		if (res != TEE_SUCCESS)
541 			goto err;
542 
543 		if (msg_len != hash_size) {
544 			res = TEE_ERROR_BAD_PARAMETERS;
545 			goto err;
546 		}
547 	}
548 
549 	bigint_size = ltc_mp.unsigned_size(ltc_key.N);
550 	if (sig_len < bigint_size) {
551 		res = TEE_ERROR_SIGNATURE_INVALID;
552 		goto err;
553 	}
554 
555 	/* Get the algorithm */
556 	if (algo != TEE_ALG_RSASSA_PKCS1_V1_5) {
557 		res = tee_algo_to_ltc_hashindex(algo, &ltc_hashindex);
558 		if (res != TEE_SUCCESS)
559 			goto err;
560 	}
561 
562 	switch (algo) {
563 	case TEE_ALG_RSASSA_PKCS1_V1_5:
564 		ltc_rsa_algo = LTC_PKCS_1_V1_5_NA1;
565 		break;
566 	case TEE_ALG_RSASSA_PKCS1_V1_5_MD5:
567 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1:
568 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224:
569 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256:
570 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384:
571 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512:
572 		ltc_rsa_algo = LTC_PKCS_1_V1_5;
573 		break;
574 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1:
575 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224:
576 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256:
577 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384:
578 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512:
579 		ltc_rsa_algo = LTC_PKCS_1_PSS;
580 		break;
581 	default:
582 		res = TEE_ERROR_BAD_PARAMETERS;
583 		goto err;
584 	}
585 
586 	ltc_res = rsa_verify_hash_ex(sig, sig_len, msg, msg_len, ltc_rsa_algo,
587 				     ltc_hashindex, salt_len, &stat, &ltc_key);
588 	res = convert_ltc_verify_status(ltc_res, stat);
589 err:
590 	return res;
591 }
592