2
0

akcipher-gcrypt.c.inc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. /*
  2. * QEMU Crypto akcipher algorithms
  3. *
  4. * Copyright (c) 2022 Bytedance
  5. * Author: lei he <helei.sig11@bytedance.com>
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  19. *
  20. */
  21. #include <gcrypt.h>
  22. #include "qemu/osdep.h"
  23. #include "qemu/host-utils.h"
  24. #include "crypto/akcipher.h"
  25. #include "crypto/random.h"
  26. #include "qapi/error.h"
  27. #include "sysemu/cryptodev.h"
  28. #include "rsakey.h"
  29. typedef struct QCryptoGcryptRSA {
  30. QCryptoAkCipher akcipher;
  31. gcry_sexp_t key;
  32. QCryptoRSAPaddingAlgorithm padding_alg;
  33. QCryptoHashAlgorithm hash_alg;
  34. } QCryptoGcryptRSA;
  35. static void qcrypto_gcrypt_rsa_free(QCryptoAkCipher *akcipher)
  36. {
  37. QCryptoGcryptRSA *rsa = (QCryptoGcryptRSA *)akcipher;
  38. if (!rsa) {
  39. return;
  40. }
  41. gcry_sexp_release(rsa->key);
  42. g_free(rsa);
  43. }
  44. static QCryptoGcryptRSA *qcrypto_gcrypt_rsa_new(
  45. const QCryptoAkCipherOptionsRSA *opt,
  46. QCryptoAkCipherKeyType type,
  47. const uint8_t *key, size_t keylen,
  48. Error **errp);
  49. QCryptoAkCipher *qcrypto_akcipher_new(const QCryptoAkCipherOptions *opts,
  50. QCryptoAkCipherKeyType type,
  51. const uint8_t *key, size_t keylen,
  52. Error **errp)
  53. {
  54. switch (opts->alg) {
  55. case QCRYPTO_AKCIPHER_ALG_RSA:
  56. return (QCryptoAkCipher *)qcrypto_gcrypt_rsa_new(
  57. &opts->u.rsa, type, key, keylen, errp);
  58. default:
  59. error_setg(errp, "Unsupported algorithm: %u", opts->alg);
  60. return NULL;
  61. }
  62. return NULL;
  63. }
  64. static void qcrypto_gcrypt_set_rsa_size(QCryptoAkCipher *akcipher, gcry_mpi_t n)
  65. {
  66. size_t key_size = (gcry_mpi_get_nbits(n) + 7) / 8;
  67. akcipher->max_plaintext_len = key_size;
  68. akcipher->max_ciphertext_len = key_size;
  69. akcipher->max_dgst_len = key_size;
  70. akcipher->max_signature_len = key_size;
  71. }
  72. static int qcrypto_gcrypt_parse_rsa_private_key(
  73. QCryptoGcryptRSA *rsa,
  74. const uint8_t *key, size_t keylen, Error **errp)
  75. {
  76. g_autoptr(QCryptoAkCipherRSAKey) rsa_key = qcrypto_akcipher_rsakey_parse(
  77. QCRYPTO_AKCIPHER_KEY_TYPE_PRIVATE, key, keylen, errp);
  78. gcry_mpi_t n = NULL, e = NULL, d = NULL, p = NULL, q = NULL, u = NULL;
  79. bool compute_mul_inv = false;
  80. int ret = -1;
  81. gcry_error_t err;
  82. if (!rsa_key) {
  83. return ret;
  84. }
  85. err = gcry_mpi_scan(&n, GCRYMPI_FMT_STD,
  86. rsa_key->n.data, rsa_key->n.len, NULL);
  87. if (gcry_err_code(err) != 0) {
  88. error_setg(errp, "Failed to parse RSA parameter n: %s/%s",
  89. gcry_strsource(err), gcry_strerror(err));
  90. goto cleanup;
  91. }
  92. err = gcry_mpi_scan(&e, GCRYMPI_FMT_STD,
  93. rsa_key->e.data, rsa_key->e.len, NULL);
  94. if (gcry_err_code(err) != 0) {
  95. error_setg(errp, "Failed to parse RSA parameter e: %s/%s",
  96. gcry_strsource(err), gcry_strerror(err));
  97. goto cleanup;
  98. }
  99. err = gcry_mpi_scan(&d, GCRYMPI_FMT_STD,
  100. rsa_key->d.data, rsa_key->d.len, NULL);
  101. if (gcry_err_code(err) != 0) {
  102. error_setg(errp, "Failed to parse RSA parameter d: %s/%s",
  103. gcry_strsource(err), gcry_strerror(err));
  104. goto cleanup;
  105. }
  106. err = gcry_mpi_scan(&p, GCRYMPI_FMT_STD,
  107. rsa_key->p.data, rsa_key->p.len, NULL);
  108. if (gcry_err_code(err) != 0) {
  109. error_setg(errp, "Failed to parse RSA parameter p: %s/%s",
  110. gcry_strsource(err), gcry_strerror(err));
  111. goto cleanup;
  112. }
  113. err = gcry_mpi_scan(&q, GCRYMPI_FMT_STD,
  114. rsa_key->q.data, rsa_key->q.len, NULL);
  115. if (gcry_err_code(err) != 0) {
  116. error_setg(errp, "Failed to parse RSA parameter q: %s/%s",
  117. gcry_strsource(err), gcry_strerror(err));
  118. goto cleanup;
  119. }
  120. if (gcry_mpi_cmp_ui(p, 0) > 0 && gcry_mpi_cmp_ui(q, 0) > 0) {
  121. compute_mul_inv = true;
  122. u = gcry_mpi_new(0);
  123. if (gcry_mpi_cmp(p, q) > 0) {
  124. gcry_mpi_swap(p, q);
  125. }
  126. gcry_mpi_invm(u, p, q);
  127. }
  128. if (compute_mul_inv) {
  129. err = gcry_sexp_build(&rsa->key, NULL,
  130. "(private-key (rsa (n %m) (e %m) (d %m) (p %m) (q %m) (u %m)))",
  131. n, e, d, p, q, u);
  132. } else {
  133. err = gcry_sexp_build(&rsa->key, NULL,
  134. "(private-key (rsa (n %m) (e %m) (d %m)))", n, e, d);
  135. }
  136. if (gcry_err_code(err) != 0) {
  137. error_setg(errp, "Failed to build RSA private key: %s/%s",
  138. gcry_strsource(err), gcry_strerror(err));
  139. goto cleanup;
  140. }
  141. qcrypto_gcrypt_set_rsa_size((QCryptoAkCipher *)rsa, n);
  142. ret = 0;
  143. cleanup:
  144. gcry_mpi_release(n);
  145. gcry_mpi_release(e);
  146. gcry_mpi_release(d);
  147. gcry_mpi_release(p);
  148. gcry_mpi_release(q);
  149. gcry_mpi_release(u);
  150. return ret;
  151. }
  152. static int qcrypto_gcrypt_parse_rsa_public_key(QCryptoGcryptRSA *rsa,
  153. const uint8_t *key,
  154. size_t keylen,
  155. Error **errp)
  156. {
  157. g_autoptr(QCryptoAkCipherRSAKey) rsa_key = qcrypto_akcipher_rsakey_parse(
  158. QCRYPTO_AKCIPHER_KEY_TYPE_PUBLIC, key, keylen, errp);
  159. gcry_mpi_t n = NULL, e = NULL;
  160. int ret = -1;
  161. gcry_error_t err;
  162. if (!rsa_key) {
  163. return ret;
  164. }
  165. err = gcry_mpi_scan(&n, GCRYMPI_FMT_STD,
  166. rsa_key->n.data, rsa_key->n.len, NULL);
  167. if (gcry_err_code(err) != 0) {
  168. error_setg(errp, "Failed to parse RSA parameter n: %s/%s",
  169. gcry_strsource(err), gcry_strerror(err));
  170. goto cleanup;
  171. }
  172. err = gcry_mpi_scan(&e, GCRYMPI_FMT_STD,
  173. rsa_key->e.data, rsa_key->e.len, NULL);
  174. if (gcry_err_code(err) != 0) {
  175. error_setg(errp, "Failed to parse RSA parameter e: %s/%s",
  176. gcry_strsource(err), gcry_strerror(err));
  177. goto cleanup;
  178. }
  179. err = gcry_sexp_build(&rsa->key, NULL,
  180. "(public-key (rsa (n %m) (e %m)))", n, e);
  181. if (gcry_err_code(err) != 0) {
  182. error_setg(errp, "Failed to build RSA public key: %s/%s",
  183. gcry_strsource(err), gcry_strerror(err));
  184. goto cleanup;
  185. }
  186. qcrypto_gcrypt_set_rsa_size((QCryptoAkCipher *)rsa, n);
  187. ret = 0;
  188. cleanup:
  189. gcry_mpi_release(n);
  190. gcry_mpi_release(e);
  191. return ret;
  192. }
  193. static int qcrypto_gcrypt_rsa_encrypt(QCryptoAkCipher *akcipher,
  194. const void *in, size_t in_len,
  195. void *out, size_t out_len,
  196. Error **errp)
  197. {
  198. QCryptoGcryptRSA *rsa = (QCryptoGcryptRSA *)akcipher;
  199. int ret = -1;
  200. gcry_sexp_t data_sexp = NULL, cipher_sexp = NULL;
  201. gcry_sexp_t cipher_sexp_item = NULL;
  202. gcry_mpi_t cipher_mpi = NULL;
  203. const char *result;
  204. gcry_error_t err;
  205. size_t actual_len;
  206. if (in_len > akcipher->max_plaintext_len) {
  207. error_setg(errp, "Plaintext length is greater than key size: %d",
  208. akcipher->max_plaintext_len);
  209. return ret;
  210. }
  211. err = gcry_sexp_build(&data_sexp, NULL,
  212. "(data (flags %s) (value %b))",
  213. QCryptoRSAPaddingAlgorithm_str(rsa->padding_alg),
  214. in_len, in);
  215. if (gcry_err_code(err) != 0) {
  216. error_setg(errp, "Failed to build plaintext: %s/%s",
  217. gcry_strsource(err), gcry_strerror(err));
  218. goto cleanup;
  219. }
  220. err = gcry_pk_encrypt(&cipher_sexp, data_sexp, rsa->key);
  221. if (gcry_err_code(err) != 0) {
  222. error_setg(errp, "Failed to encrypt: %s/%s",
  223. gcry_strsource(err), gcry_strerror(err));
  224. goto cleanup;
  225. }
  226. /* S-expression of cipher: (enc-val (rsa (a a-mpi))) */
  227. cipher_sexp_item = gcry_sexp_find_token(cipher_sexp, "a", 0);
  228. if (!cipher_sexp_item || gcry_sexp_length(cipher_sexp_item) != 2) {
  229. error_setg(errp, "Invalid ciphertext result");
  230. goto cleanup;
  231. }
  232. if (rsa->padding_alg == QCRYPTO_RSA_PADDING_ALG_RAW) {
  233. cipher_mpi = gcry_sexp_nth_mpi(cipher_sexp_item, 1, GCRYMPI_FMT_USG);
  234. if (!cipher_mpi) {
  235. error_setg(errp, "Invalid ciphertext result");
  236. goto cleanup;
  237. }
  238. err = gcry_mpi_print(GCRYMPI_FMT_USG, out, out_len,
  239. &actual_len, cipher_mpi);
  240. if (gcry_err_code(err) != 0) {
  241. error_setg(errp, "Failed to print MPI: %s/%s",
  242. gcry_strsource(err), gcry_strerror(err));
  243. goto cleanup;
  244. }
  245. if (actual_len > out_len) {
  246. error_setg(errp, "Ciphertext buffer length is too small");
  247. goto cleanup;
  248. }
  249. /* We always padding leading-zeros for RSA-RAW */
  250. if (actual_len < out_len) {
  251. memmove((uint8_t *)out + (out_len - actual_len), out, actual_len);
  252. memset(out, 0, out_len - actual_len);
  253. }
  254. ret = out_len;
  255. } else {
  256. result = gcry_sexp_nth_data(cipher_sexp_item, 1, &actual_len);
  257. if (!result) {
  258. error_setg(errp, "Invalid ciphertext result");
  259. goto cleanup;
  260. }
  261. if (actual_len > out_len) {
  262. error_setg(errp, "Ciphertext buffer length is too small");
  263. goto cleanup;
  264. }
  265. memcpy(out, result, actual_len);
  266. ret = actual_len;
  267. }
  268. cleanup:
  269. gcry_sexp_release(data_sexp);
  270. gcry_sexp_release(cipher_sexp);
  271. gcry_sexp_release(cipher_sexp_item);
  272. gcry_mpi_release(cipher_mpi);
  273. return ret;
  274. }
  275. static int qcrypto_gcrypt_rsa_decrypt(QCryptoAkCipher *akcipher,
  276. const void *in, size_t in_len,
  277. void *out, size_t out_len,
  278. Error **errp)
  279. {
  280. QCryptoGcryptRSA *rsa = (QCryptoGcryptRSA *)akcipher;
  281. int ret = -1;
  282. gcry_sexp_t data_sexp = NULL, cipher_sexp = NULL;
  283. gcry_mpi_t data_mpi = NULL;
  284. gcry_error_t err;
  285. size_t actual_len;
  286. const char *result;
  287. if (in_len > akcipher->max_ciphertext_len) {
  288. error_setg(errp, "Ciphertext length is greater than key size: %d",
  289. akcipher->max_ciphertext_len);
  290. return ret;
  291. }
  292. err = gcry_sexp_build(&cipher_sexp, NULL,
  293. "(enc-val (flags %s) (rsa (a %b) ))",
  294. QCryptoRSAPaddingAlgorithm_str(rsa->padding_alg),
  295. in_len, in);
  296. if (gcry_err_code(err) != 0) {
  297. error_setg(errp, "Failed to build ciphertext: %s/%s",
  298. gcry_strsource(err), gcry_strerror(err));
  299. goto cleanup;
  300. }
  301. err = gcry_pk_decrypt(&data_sexp, cipher_sexp, rsa->key);
  302. if (gcry_err_code(err) != 0) {
  303. error_setg(errp, "Failed to decrypt: %s/%s",
  304. gcry_strsource(err), gcry_strerror(err));
  305. goto cleanup;
  306. }
  307. /* S-expression of plaintext: (value plaintext) */
  308. if (rsa->padding_alg == QCRYPTO_RSA_PADDING_ALG_RAW) {
  309. data_mpi = gcry_sexp_nth_mpi(data_sexp, 1, GCRYMPI_FMT_USG);
  310. if (!data_mpi) {
  311. error_setg(errp, "Invalid plaintext result");
  312. goto cleanup;
  313. }
  314. err = gcry_mpi_print(GCRYMPI_FMT_USG, out, out_len,
  315. &actual_len, data_mpi);
  316. if (gcry_err_code(err) != 0) {
  317. error_setg(errp, "Failed to print MPI: %s/%s",
  318. gcry_strsource(err), gcry_strerror(err));
  319. goto cleanup;
  320. }
  321. if (actual_len > out_len) {
  322. error_setg(errp, "Plaintext buffer length is too small");
  323. goto cleanup;
  324. }
  325. /* We always padding leading-zeros for RSA-RAW */
  326. if (actual_len < out_len) {
  327. memmove((uint8_t *)out + (out_len - actual_len), out, actual_len);
  328. memset(out, 0, out_len - actual_len);
  329. }
  330. ret = out_len;
  331. } else {
  332. result = gcry_sexp_nth_data(data_sexp, 1, &actual_len);
  333. if (!result) {
  334. error_setg(errp, "Invalid plaintext result");
  335. goto cleanup;
  336. }
  337. if (actual_len > out_len) {
  338. error_setg(errp, "Plaintext buffer length is too small");
  339. goto cleanup;
  340. }
  341. memcpy(out, result, actual_len);
  342. ret = actual_len;
  343. }
  344. cleanup:
  345. gcry_sexp_release(cipher_sexp);
  346. gcry_sexp_release(data_sexp);
  347. gcry_mpi_release(data_mpi);
  348. return ret;
  349. }
  350. static int qcrypto_gcrypt_rsa_sign(QCryptoAkCipher *akcipher,
  351. const void *in, size_t in_len,
  352. void *out, size_t out_len, Error **errp)
  353. {
  354. QCryptoGcryptRSA *rsa = (QCryptoGcryptRSA *)akcipher;
  355. int ret = -1;
  356. gcry_sexp_t dgst_sexp = NULL, sig_sexp = NULL;
  357. gcry_sexp_t sig_sexp_item = NULL;
  358. const char *result;
  359. gcry_error_t err;
  360. size_t actual_len;
  361. if (in_len > akcipher->max_dgst_len) {
  362. error_setg(errp, "Data length is greater than key size: %d",
  363. akcipher->max_dgst_len);
  364. return ret;
  365. }
  366. if (rsa->padding_alg != QCRYPTO_RSA_PADDING_ALG_PKCS1) {
  367. error_setg(errp, "Invalid padding %u", rsa->padding_alg);
  368. return ret;
  369. }
  370. err = gcry_sexp_build(&dgst_sexp, NULL,
  371. "(data (flags pkcs1) (hash %s %b))",
  372. QCryptoHashAlgorithm_str(rsa->hash_alg),
  373. in_len, in);
  374. if (gcry_err_code(err) != 0) {
  375. error_setg(errp, "Failed to build dgst: %s/%s",
  376. gcry_strsource(err), gcry_strerror(err));
  377. goto cleanup;
  378. }
  379. err = gcry_pk_sign(&sig_sexp, dgst_sexp, rsa->key);
  380. if (gcry_err_code(err) != 0) {
  381. error_setg(errp, "Failed to make signature: %s/%s",
  382. gcry_strsource(err), gcry_strerror(err));
  383. goto cleanup;
  384. }
  385. /* S-expression of signature: (sig-val (rsa (s s-mpi))) */
  386. sig_sexp_item = gcry_sexp_find_token(sig_sexp, "s", 0);
  387. if (!sig_sexp_item || gcry_sexp_length(sig_sexp_item) != 2) {
  388. error_setg(errp, "Invalid signature result");
  389. goto cleanup;
  390. }
  391. result = gcry_sexp_nth_data(sig_sexp_item, 1, &actual_len);
  392. if (!result) {
  393. error_setg(errp, "Invalid signature result");
  394. goto cleanup;
  395. }
  396. if (actual_len > out_len) {
  397. error_setg(errp, "Signature buffer length is too small");
  398. goto cleanup;
  399. }
  400. memcpy(out, result, actual_len);
  401. ret = actual_len;
  402. cleanup:
  403. gcry_sexp_release(dgst_sexp);
  404. gcry_sexp_release(sig_sexp);
  405. gcry_sexp_release(sig_sexp_item);
  406. return ret;
  407. }
  408. static int qcrypto_gcrypt_rsa_verify(QCryptoAkCipher *akcipher,
  409. const void *in, size_t in_len,
  410. const void *in2, size_t in2_len,
  411. Error **errp)
  412. {
  413. QCryptoGcryptRSA *rsa = (QCryptoGcryptRSA *)akcipher;
  414. int ret = -1;
  415. gcry_sexp_t sig_sexp = NULL, dgst_sexp = NULL;
  416. gcry_error_t err;
  417. if (in_len > akcipher->max_signature_len) {
  418. error_setg(errp, "Signature length is greater than key size: %d",
  419. akcipher->max_signature_len);
  420. return ret;
  421. }
  422. if (in2_len > akcipher->max_dgst_len) {
  423. error_setg(errp, "Data length is greater than key size: %d",
  424. akcipher->max_dgst_len);
  425. return ret;
  426. }
  427. if (rsa->padding_alg != QCRYPTO_RSA_PADDING_ALG_PKCS1) {
  428. error_setg(errp, "Invalid padding %u", rsa->padding_alg);
  429. return ret;
  430. }
  431. err = gcry_sexp_build(&sig_sexp, NULL,
  432. "(sig-val (rsa (s %b)))", in_len, in);
  433. if (gcry_err_code(err) != 0) {
  434. error_setg(errp, "Failed to build signature: %s/%s",
  435. gcry_strsource(err), gcry_strerror(err));
  436. goto cleanup;
  437. }
  438. err = gcry_sexp_build(&dgst_sexp, NULL,
  439. "(data (flags pkcs1) (hash %s %b))",
  440. QCryptoHashAlgorithm_str(rsa->hash_alg),
  441. in2_len, in2);
  442. if (gcry_err_code(err) != 0) {
  443. error_setg(errp, "Failed to build dgst: %s/%s",
  444. gcry_strsource(err), gcry_strerror(err));
  445. goto cleanup;
  446. }
  447. err = gcry_pk_verify(sig_sexp, dgst_sexp, rsa->key);
  448. if (gcry_err_code(err) != 0) {
  449. error_setg(errp, "Failed to verify signature: %s/%s",
  450. gcry_strsource(err), gcry_strerror(err));
  451. goto cleanup;
  452. }
  453. ret = 0;
  454. cleanup:
  455. gcry_sexp_release(dgst_sexp);
  456. gcry_sexp_release(sig_sexp);
  457. return ret;
  458. }
  459. QCryptoAkCipherDriver gcrypt_rsa = {
  460. .encrypt = qcrypto_gcrypt_rsa_encrypt,
  461. .decrypt = qcrypto_gcrypt_rsa_decrypt,
  462. .sign = qcrypto_gcrypt_rsa_sign,
  463. .verify = qcrypto_gcrypt_rsa_verify,
  464. .free = qcrypto_gcrypt_rsa_free,
  465. };
  466. static QCryptoGcryptRSA *qcrypto_gcrypt_rsa_new(
  467. const QCryptoAkCipherOptionsRSA *opt,
  468. QCryptoAkCipherKeyType type,
  469. const uint8_t *key, size_t keylen,
  470. Error **errp)
  471. {
  472. QCryptoGcryptRSA *rsa = g_new0(QCryptoGcryptRSA, 1);
  473. rsa->padding_alg = opt->padding_alg;
  474. rsa->hash_alg = opt->hash_alg;
  475. rsa->akcipher.driver = &gcrypt_rsa;
  476. switch (type) {
  477. case QCRYPTO_AKCIPHER_KEY_TYPE_PRIVATE:
  478. if (qcrypto_gcrypt_parse_rsa_private_key(rsa, key, keylen, errp) != 0) {
  479. goto error;
  480. }
  481. break;
  482. case QCRYPTO_AKCIPHER_KEY_TYPE_PUBLIC:
  483. if (qcrypto_gcrypt_parse_rsa_public_key(rsa, key, keylen, errp) != 0) {
  484. goto error;
  485. }
  486. break;
  487. default:
  488. error_setg(errp, "Unknown akcipher key type %d", type);
  489. goto error;
  490. }
  491. return rsa;
  492. error:
  493. qcrypto_gcrypt_rsa_free((QCryptoAkCipher *)rsa);
  494. return NULL;
  495. }
  496. bool qcrypto_akcipher_supports(QCryptoAkCipherOptions *opts)
  497. {
  498. switch (opts->alg) {
  499. case QCRYPTO_AKCIPHER_ALG_RSA:
  500. switch (opts->u.rsa.padding_alg) {
  501. case QCRYPTO_RSA_PADDING_ALG_RAW:
  502. return true;
  503. case QCRYPTO_RSA_PADDING_ALG_PKCS1:
  504. switch (opts->u.rsa.hash_alg) {
  505. case QCRYPTO_HASH_ALG_MD5:
  506. case QCRYPTO_HASH_ALG_SHA1:
  507. case QCRYPTO_HASH_ALG_SHA256:
  508. case QCRYPTO_HASH_ALG_SHA512:
  509. return true;
  510. default:
  511. return false;
  512. }
  513. default:
  514. return false;
  515. }
  516. default:
  517. return true;
  518. }
  519. }