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/>.
25 static int extract_mpi(void *ctx, const uint8_t *value,
26 size_t vlen, Error **errp)
28 QCryptoAkCipherMPI *mpi = (QCryptoAkCipherMPI *)ctx;
30 error_setg(errp, "Empty mpi field");
33 mpi->data = g_memdup2(value, vlen);
38 static int extract_version(void *ctx, const uint8_t *value,
39 size_t vlen, Error **errp)
41 uint8_t *version = (uint8_t *)ctx;
42 if (vlen != 1 || *value > 1) {
43 error_setg(errp, "Invalid rsakey version");
50 static int extract_seq_content(void *ctx, const uint8_t *value,
51 size_t vlen, Error **errp)
53 const uint8_t **content = (const uint8_t **)ctx;
55 error_setg(errp, "Empty sequence");
64 * RsaPubKey ::= SEQUENCE {
69 static QCryptoAkCipherRSAKey *qcrypto_builtin_rsa_public_key_parse(
70 const uint8_t *key, size_t keylen, Error **errp)
72 QCryptoAkCipherRSAKey *rsa = g_new0(QCryptoAkCipherRSAKey, 1);
77 decode_ret = qcrypto_der_decode_seq(&key, &keylen,
78 extract_seq_content, &seq, errp);
79 if (decode_ret < 0 || keylen != 0) {
82 seq_length = decode_ret;
84 if (qcrypto_der_decode_int(&seq, &seq_length, extract_mpi,
86 qcrypto_der_decode_int(&seq, &seq_length, extract_mpi,
90 if (seq_length != 0) {
98 error_setg(errp, "Invalid RSA public key");
100 qcrypto_akcipher_rsakey_free(rsa);
105 * RsaPrivKey ::= SEQUENCE {
115 * otherPrimeInfos OtherPrimeInfos OPTIONAL
118 static QCryptoAkCipherRSAKey *qcrypto_builtin_rsa_private_key_parse(
119 const uint8_t *key, size_t keylen, Error **errp)
121 QCryptoAkCipherRSAKey *rsa = g_new0(QCryptoAkCipherRSAKey, 1);
127 decode_ret = qcrypto_der_decode_seq(&key, &keylen, extract_seq_content,
129 if (decode_ret < 0 || keylen != 0) {
132 seq_length = decode_ret;
134 decode_ret = qcrypto_der_decode_int(&seq, &seq_length, extract_version,
137 if (qcrypto_der_decode_int(&seq, &seq_length, extract_mpi,
138 &rsa->n, errp) < 0 ||
139 qcrypto_der_decode_int(&seq, &seq_length, extract_mpi,
140 &rsa->e, errp) < 0 ||
141 qcrypto_der_decode_int(&seq, &seq_length, extract_mpi,
142 &rsa->d, errp) < 0 ||
143 qcrypto_der_decode_int(&seq, &seq_length, extract_mpi, &rsa->p,
145 qcrypto_der_decode_int(&seq, &seq_length, extract_mpi, &rsa->q,
147 qcrypto_der_decode_int(&seq, &seq_length, extract_mpi, &rsa->dp,
149 qcrypto_der_decode_int(&seq, &seq_length, extract_mpi, &rsa->dq,
151 qcrypto_der_decode_int(&seq, &seq_length, extract_mpi, &rsa->u,
157 * According to the standard, otherPrimeInfos must be present for version 1.
158 * There is no strict verification here, this is to be compatible with
159 * the unit test of the kernel. TODO: remove this until linux kernel's
160 * unit-test is fixed.
162 if (version == 1 && seq_length != 0) {
163 if (qcrypto_der_decode_seq(&seq, &seq_length, NULL, NULL, errp) < 0) {
166 if (seq_length != 0) {
171 if (seq_length != 0) {
178 if (errp && !*errp) {
179 error_setg(errp, "Invalid RSA private key");
181 qcrypto_akcipher_rsakey_free(rsa);
185 QCryptoAkCipherRSAKey *qcrypto_akcipher_rsakey_parse(
186 QCryptoAkCipherKeyType type, const uint8_t *key,
187 size_t keylen, Error **errp)
190 case QCRYPTO_AKCIPHER_KEY_TYPE_PRIVATE:
191 return qcrypto_builtin_rsa_private_key_parse(key, keylen, errp);
193 case QCRYPTO_AKCIPHER_KEY_TYPE_PUBLIC:
194 return qcrypto_builtin_rsa_public_key_parse(key, keylen, errp);
197 error_setg(errp, "Unknown key type: %d", type);