2 * QEMU Crypto akcipher algorithms
4 * Copyright (c) 2022 Bytedance
5 * Author: lei he <helei.sig11@bytedance.com>
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.
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.
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/>.
24 #include "qemu/osdep.h"
25 #include "qemu/host-utils.h"
26 #include "crypto/akcipher.h"
27 #include "crypto/random.h"
28 #include "qapi/error.h"
29 #include "sysemu/cryptodev.h"
32 typedef struct QCryptoGcryptRSA {
33 QCryptoAkCipher akcipher;
35 QCryptoRSAPaddingAlgorithm padding_alg;
36 QCryptoHashAlgorithm hash_alg;
39 static void qcrypto_gcrypt_rsa_free(QCryptoAkCipher *akcipher)
41 QCryptoGcryptRSA *rsa = (QCryptoGcryptRSA *)akcipher;
46 gcry_sexp_release(rsa->key);
50 static QCryptoGcryptRSA *qcrypto_gcrypt_rsa_new(
51 const QCryptoAkCipherOptionsRSA *opt,
52 QCryptoAkCipherKeyType type,
53 const uint8_t *key, size_t keylen,
56 QCryptoAkCipher *qcrypto_akcipher_new(const QCryptoAkCipherOptions *opts,
57 QCryptoAkCipherKeyType type,
58 const uint8_t *key, size_t keylen,
62 case QCRYPTO_AKCIPHER_ALG_RSA:
63 return (QCryptoAkCipher *)qcrypto_gcrypt_rsa_new(
64 &opts->u.rsa, type, key, keylen, errp);
67 error_setg(errp, "Unsupported algorithm: %u", opts->alg);
74 static void qcrypto_gcrypt_set_rsa_size(QCryptoAkCipher *akcipher, gcry_mpi_t n)
76 size_t key_size = (gcry_mpi_get_nbits(n) + 7) / 8;
77 akcipher->max_plaintext_len = key_size;
78 akcipher->max_ciphertext_len = key_size;
79 akcipher->max_dgst_len = key_size;
80 akcipher->max_signature_len = key_size;
83 static int qcrypto_gcrypt_parse_rsa_private_key(
84 QCryptoGcryptRSA *rsa,
85 const uint8_t *key, size_t keylen, Error **errp)
87 g_autoptr(QCryptoAkCipherRSAKey) rsa_key = qcrypto_akcipher_rsakey_parse(
88 QCRYPTO_AKCIPHER_KEY_TYPE_PRIVATE, key, keylen, errp);
89 gcry_mpi_t n = NULL, e = NULL, d = NULL, p = NULL, q = NULL, u = NULL;
90 bool compute_mul_inv = false;
98 err = gcry_mpi_scan(&n, GCRYMPI_FMT_STD,
99 rsa_key->n.data, rsa_key->n.len, NULL);
100 if (gcry_err_code(err) != 0) {
101 error_setg(errp, "Failed to parse RSA parameter n: %s/%s",
102 gcry_strsource(err), gcry_strerror(err));
106 err = gcry_mpi_scan(&e, GCRYMPI_FMT_STD,
107 rsa_key->e.data, rsa_key->e.len, NULL);
108 if (gcry_err_code(err) != 0) {
109 error_setg(errp, "Failed to parse RSA parameter e: %s/%s",
110 gcry_strsource(err), gcry_strerror(err));
114 err = gcry_mpi_scan(&d, GCRYMPI_FMT_STD,
115 rsa_key->d.data, rsa_key->d.len, NULL);
116 if (gcry_err_code(err) != 0) {
117 error_setg(errp, "Failed to parse RSA parameter d: %s/%s",
118 gcry_strsource(err), gcry_strerror(err));
122 err = gcry_mpi_scan(&p, GCRYMPI_FMT_STD,
123 rsa_key->p.data, rsa_key->p.len, NULL);
124 if (gcry_err_code(err) != 0) {
125 error_setg(errp, "Failed to parse RSA parameter p: %s/%s",
126 gcry_strsource(err), gcry_strerror(err));
130 err = gcry_mpi_scan(&q, GCRYMPI_FMT_STD,
131 rsa_key->q.data, rsa_key->q.len, NULL);
132 if (gcry_err_code(err) != 0) {
133 error_setg(errp, "Failed to parse RSA parameter q: %s/%s",
134 gcry_strsource(err), gcry_strerror(err));
138 if (gcry_mpi_cmp_ui(p, 0) > 0 && gcry_mpi_cmp_ui(q, 0) > 0) {
139 compute_mul_inv = true;
142 if (gcry_mpi_cmp(p, q) > 0) {
145 gcry_mpi_invm(u, p, q);
148 if (compute_mul_inv) {
149 err = gcry_sexp_build(&rsa->key, NULL,
150 "(private-key (rsa (n %m) (e %m) (d %m) (p %m) (q %m) (u %m)))",
153 err = gcry_sexp_build(&rsa->key, NULL,
154 "(private-key (rsa (n %m) (e %m) (d %m)))", n, e, d);
156 if (gcry_err_code(err) != 0) {
157 error_setg(errp, "Failed to build RSA private key: %s/%s",
158 gcry_strsource(err), gcry_strerror(err));
161 qcrypto_gcrypt_set_rsa_size((QCryptoAkCipher *)rsa, n);
174 static int qcrypto_gcrypt_parse_rsa_public_key(QCryptoGcryptRSA *rsa,
180 g_autoptr(QCryptoAkCipherRSAKey) rsa_key = qcrypto_akcipher_rsakey_parse(
181 QCRYPTO_AKCIPHER_KEY_TYPE_PUBLIC, key, keylen, errp);
182 gcry_mpi_t n = NULL, e = NULL;
190 err = gcry_mpi_scan(&n, GCRYMPI_FMT_STD,
191 rsa_key->n.data, rsa_key->n.len, NULL);
192 if (gcry_err_code(err) != 0) {
193 error_setg(errp, "Failed to parse RSA parameter n: %s/%s",
194 gcry_strsource(err), gcry_strerror(err));
198 err = gcry_mpi_scan(&e, GCRYMPI_FMT_STD,
199 rsa_key->e.data, rsa_key->e.len, NULL);
200 if (gcry_err_code(err) != 0) {
201 error_setg(errp, "Failed to parse RSA parameter e: %s/%s",
202 gcry_strsource(err), gcry_strerror(err));
206 err = gcry_sexp_build(&rsa->key, NULL,
207 "(public-key (rsa (n %m) (e %m)))", n, e);
208 if (gcry_err_code(err) != 0) {
209 error_setg(errp, "Failed to build RSA public key: %s/%s",
210 gcry_strsource(err), gcry_strerror(err));
213 qcrypto_gcrypt_set_rsa_size((QCryptoAkCipher *)rsa, n);
222 static int qcrypto_gcrypt_rsa_encrypt(QCryptoAkCipher *akcipher,
223 const void *in, size_t in_len,
224 void *out, size_t out_len,
227 QCryptoGcryptRSA *rsa = (QCryptoGcryptRSA *)akcipher;
229 gcry_sexp_t data_sexp = NULL, cipher_sexp = NULL;
230 gcry_sexp_t cipher_sexp_item = NULL;
231 gcry_mpi_t cipher_mpi = NULL;
236 if (in_len > akcipher->max_plaintext_len) {
237 error_setg(errp, "Plaintext length is greater than key size: %d",
238 akcipher->max_plaintext_len);
242 err = gcry_sexp_build(&data_sexp, NULL,
243 "(data (flags %s) (value %b))",
244 QCryptoRSAPaddingAlgorithm_str(rsa->padding_alg),
246 if (gcry_err_code(err) != 0) {
247 error_setg(errp, "Failed to build plaintext: %s/%s",
248 gcry_strsource(err), gcry_strerror(err));
252 err = gcry_pk_encrypt(&cipher_sexp, data_sexp, rsa->key);
253 if (gcry_err_code(err) != 0) {
254 error_setg(errp, "Failed to encrypt: %s/%s",
255 gcry_strsource(err), gcry_strerror(err));
259 /* S-expression of cipher: (enc-val (rsa (a a-mpi))) */
260 cipher_sexp_item = gcry_sexp_find_token(cipher_sexp, "a", 0);
261 if (!cipher_sexp_item || gcry_sexp_length(cipher_sexp_item) != 2) {
262 error_setg(errp, "Invalid ciphertext result");
266 if (rsa->padding_alg == QCRYPTO_RSA_PADDING_ALG_RAW) {
267 cipher_mpi = gcry_sexp_nth_mpi(cipher_sexp_item, 1, GCRYMPI_FMT_USG);
269 error_setg(errp, "Invalid ciphertext result");
272 err = gcry_mpi_print(GCRYMPI_FMT_USG, out, out_len,
273 &actual_len, cipher_mpi);
274 if (gcry_err_code(err) != 0) {
275 error_setg(errp, "Failed to print MPI: %s/%s",
276 gcry_strsource(err), gcry_strerror(err));
280 if (actual_len > out_len) {
281 error_setg(errp, "Ciphertext buffer length is too small");
285 /* We always padding leading-zeros for RSA-RAW */
286 if (actual_len < out_len) {
287 memmove((uint8_t *)out + (out_len - actual_len), out, actual_len);
288 memset(out, 0, out_len - actual_len);
293 result = gcry_sexp_nth_data(cipher_sexp_item, 1, &actual_len);
295 error_setg(errp, "Invalid ciphertext result");
298 if (actual_len > out_len) {
299 error_setg(errp, "Ciphertext buffer length is too small");
302 memcpy(out, result, actual_len);
307 gcry_sexp_release(data_sexp);
308 gcry_sexp_release(cipher_sexp);
309 gcry_sexp_release(cipher_sexp_item);
310 gcry_mpi_release(cipher_mpi);
314 static int qcrypto_gcrypt_rsa_decrypt(QCryptoAkCipher *akcipher,
315 const void *in, size_t in_len,
316 void *out, size_t out_len,
319 QCryptoGcryptRSA *rsa = (QCryptoGcryptRSA *)akcipher;
321 gcry_sexp_t data_sexp = NULL, cipher_sexp = NULL;
322 gcry_mpi_t data_mpi = NULL;
327 if (in_len > akcipher->max_ciphertext_len) {
328 error_setg(errp, "Ciphertext length is greater than key size: %d",
329 akcipher->max_ciphertext_len);
333 err = gcry_sexp_build(&cipher_sexp, NULL,
334 "(enc-val (flags %s) (rsa (a %b) ))",
335 QCryptoRSAPaddingAlgorithm_str(rsa->padding_alg),
337 if (gcry_err_code(err) != 0) {
338 error_setg(errp, "Failed to build ciphertext: %s/%s",
339 gcry_strsource(err), gcry_strerror(err));
343 err = gcry_pk_decrypt(&data_sexp, cipher_sexp, rsa->key);
344 if (gcry_err_code(err) != 0) {
345 error_setg(errp, "Failed to decrypt: %s/%s",
346 gcry_strsource(err), gcry_strerror(err));
350 /* S-expression of plaintext: (value plaintext) */
351 if (rsa->padding_alg == QCRYPTO_RSA_PADDING_ALG_RAW) {
352 data_mpi = gcry_sexp_nth_mpi(data_sexp, 1, GCRYMPI_FMT_USG);
354 error_setg(errp, "Invalid plaintext result");
357 err = gcry_mpi_print(GCRYMPI_FMT_USG, out, out_len,
358 &actual_len, data_mpi);
359 if (gcry_err_code(err) != 0) {
360 error_setg(errp, "Failed to print MPI: %s/%s",
361 gcry_strsource(err), gcry_strerror(err));
364 if (actual_len > out_len) {
365 error_setg(errp, "Plaintext buffer length is too small");
368 /* We always padding leading-zeros for RSA-RAW */
369 if (actual_len < out_len) {
370 memmove((uint8_t *)out + (out_len - actual_len), out, actual_len);
371 memset(out, 0, out_len - actual_len);
375 result = gcry_sexp_nth_data(data_sexp, 1, &actual_len);
377 error_setg(errp, "Invalid plaintext result");
380 if (actual_len > out_len) {
381 error_setg(errp, "Plaintext buffer length is too small");
384 memcpy(out, result, actual_len);
389 gcry_sexp_release(cipher_sexp);
390 gcry_sexp_release(data_sexp);
391 gcry_mpi_release(data_mpi);
395 static int qcrypto_gcrypt_rsa_sign(QCryptoAkCipher *akcipher,
396 const void *in, size_t in_len,
397 void *out, size_t out_len, Error **errp)
399 QCryptoGcryptRSA *rsa = (QCryptoGcryptRSA *)akcipher;
401 gcry_sexp_t dgst_sexp = NULL, sig_sexp = NULL;
402 gcry_sexp_t sig_sexp_item = NULL;
407 if (in_len > akcipher->max_dgst_len) {
408 error_setg(errp, "Data length is greater than key size: %d",
409 akcipher->max_dgst_len);
413 if (rsa->padding_alg != QCRYPTO_RSA_PADDING_ALG_PKCS1) {
414 error_setg(errp, "Invalid padding %u", rsa->padding_alg);
418 err = gcry_sexp_build(&dgst_sexp, NULL,
419 "(data (flags pkcs1) (hash %s %b))",
420 QCryptoHashAlgorithm_str(rsa->hash_alg),
422 if (gcry_err_code(err) != 0) {
423 error_setg(errp, "Failed to build dgst: %s/%s",
424 gcry_strsource(err), gcry_strerror(err));
428 err = gcry_pk_sign(&sig_sexp, dgst_sexp, rsa->key);
429 if (gcry_err_code(err) != 0) {
430 error_setg(errp, "Failed to make signature: %s/%s",
431 gcry_strsource(err), gcry_strerror(err));
435 /* S-expression of signature: (sig-val (rsa (s s-mpi))) */
436 sig_sexp_item = gcry_sexp_find_token(sig_sexp, "s", 0);
437 if (!sig_sexp_item || gcry_sexp_length(sig_sexp_item) != 2) {
438 error_setg(errp, "Invalid signature result");
442 result = gcry_sexp_nth_data(sig_sexp_item, 1, &actual_len);
444 error_setg(errp, "Invalid signature result");
448 if (actual_len > out_len) {
449 error_setg(errp, "Signature buffer length is too small");
452 memcpy(out, result, actual_len);
456 gcry_sexp_release(dgst_sexp);
457 gcry_sexp_release(sig_sexp);
458 gcry_sexp_release(sig_sexp_item);
463 static int qcrypto_gcrypt_rsa_verify(QCryptoAkCipher *akcipher,
464 const void *in, size_t in_len,
465 const void *in2, size_t in2_len,
468 QCryptoGcryptRSA *rsa = (QCryptoGcryptRSA *)akcipher;
470 gcry_sexp_t sig_sexp = NULL, dgst_sexp = NULL;
473 if (in_len > akcipher->max_signature_len) {
474 error_setg(errp, "Signature length is greater than key size: %d",
475 akcipher->max_signature_len);
479 if (in2_len > akcipher->max_dgst_len) {
480 error_setg(errp, "Data length is greater than key size: %d",
481 akcipher->max_dgst_len);
485 if (rsa->padding_alg != QCRYPTO_RSA_PADDING_ALG_PKCS1) {
486 error_setg(errp, "Invalid padding %u", rsa->padding_alg);
490 err = gcry_sexp_build(&sig_sexp, NULL,
491 "(sig-val (rsa (s %b)))", in_len, in);
492 if (gcry_err_code(err) != 0) {
493 error_setg(errp, "Failed to build signature: %s/%s",
494 gcry_strsource(err), gcry_strerror(err));
498 err = gcry_sexp_build(&dgst_sexp, NULL,
499 "(data (flags pkcs1) (hash %s %b))",
500 QCryptoHashAlgorithm_str(rsa->hash_alg),
502 if (gcry_err_code(err) != 0) {
503 error_setg(errp, "Failed to build dgst: %s/%s",
504 gcry_strsource(err), gcry_strerror(err));
508 err = gcry_pk_verify(sig_sexp, dgst_sexp, rsa->key);
509 if (gcry_err_code(err) != 0) {
510 error_setg(errp, "Failed to verify signature: %s/%s",
511 gcry_strsource(err), gcry_strerror(err));
517 gcry_sexp_release(dgst_sexp);
518 gcry_sexp_release(sig_sexp);
523 QCryptoAkCipherDriver gcrypt_rsa = {
524 .encrypt = qcrypto_gcrypt_rsa_encrypt,
525 .decrypt = qcrypto_gcrypt_rsa_decrypt,
526 .sign = qcrypto_gcrypt_rsa_sign,
527 .verify = qcrypto_gcrypt_rsa_verify,
528 .free = qcrypto_gcrypt_rsa_free,
531 static QCryptoGcryptRSA *qcrypto_gcrypt_rsa_new(
532 const QCryptoAkCipherOptionsRSA *opt,
533 QCryptoAkCipherKeyType type,
534 const uint8_t *key, size_t keylen,
537 QCryptoGcryptRSA *rsa = g_new0(QCryptoGcryptRSA, 1);
538 rsa->padding_alg = opt->padding_alg;
539 rsa->hash_alg = opt->hash_alg;
540 rsa->akcipher.driver = &gcrypt_rsa;
543 case QCRYPTO_AKCIPHER_KEY_TYPE_PRIVATE:
544 if (qcrypto_gcrypt_parse_rsa_private_key(rsa, key, keylen, errp) != 0) {
549 case QCRYPTO_AKCIPHER_KEY_TYPE_PUBLIC:
550 if (qcrypto_gcrypt_parse_rsa_public_key(rsa, key, keylen, errp) != 0) {
556 error_setg(errp, "Unknown akcipher key type %d", type);
563 qcrypto_gcrypt_rsa_free((QCryptoAkCipher *)rsa);
568 bool qcrypto_akcipher_supports(QCryptoAkCipherOptions *opts)
571 case QCRYPTO_AKCIPHER_ALG_RSA:
572 switch (opts->u.rsa.padding_alg) {
573 case QCRYPTO_RSA_PADDING_ALG_RAW:
576 case QCRYPTO_RSA_PADDING_ALG_PKCS1:
577 switch (opts->u.rsa.hash_alg) {
578 case QCRYPTO_HASH_ALG_MD5:
579 case QCRYPTO_HASH_ALG_SHA1:
580 case QCRYPTO_HASH_ALG_SHA256:
581 case QCRYPTO_HASH_ALG_SHA512: