xref: /openbmc/qemu/crypto/rsakey-nettle.c.inc (revision 4c5e512ee0c49efb42286600aef31739c0dcee5d)
1*4c5e512eSLei He/*
2*4c5e512eSLei He * QEMU Crypto akcipher algorithms
3*4c5e512eSLei He *
4*4c5e512eSLei He * Copyright (c) 2022 Bytedance
5*4c5e512eSLei He * Author: lei he <helei.sig11@bytedance.com>
6*4c5e512eSLei He *
7*4c5e512eSLei He * This library is free software; you can redistribute it and/or
8*4c5e512eSLei He * modify it under the terms of the GNU Lesser General Public
9*4c5e512eSLei He * License as published by the Free Software Foundation; either
10*4c5e512eSLei He * version 2.1 of the License, or (at your option) any later version.
11*4c5e512eSLei He *
12*4c5e512eSLei He * This library is distributed in the hope that it will be useful,
13*4c5e512eSLei He * but WITHOUT ANY WARRANTY; without even the implied warranty of
14*4c5e512eSLei He * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15*4c5e512eSLei He * Lesser General Public License for more details.
16*4c5e512eSLei He *
17*4c5e512eSLei He * You should have received a copy of the GNU Lesser General Public
18*4c5e512eSLei He * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19*4c5e512eSLei He *
20*4c5e512eSLei He */
21*4c5e512eSLei He
22*4c5e512eSLei He#include <nettle/asn1.h>
23*4c5e512eSLei He
24*4c5e512eSLei He#include "qemu/osdep.h"
25*4c5e512eSLei He#include "qapi/error.h"
26*4c5e512eSLei He#include "rsakey.h"
27*4c5e512eSLei He
28*4c5e512eSLei Hestatic bool DumpMPI(struct asn1_der_iterator *i, QCryptoAkCipherMPI *mpi)
29*4c5e512eSLei He{
30*4c5e512eSLei He    mpi->data = g_memdup2(i->data, i->length);
31*4c5e512eSLei He    mpi->len = i->length;
32*4c5e512eSLei He    return true;
33*4c5e512eSLei He}
34*4c5e512eSLei He
35*4c5e512eSLei Hestatic bool GetMPI(struct asn1_der_iterator *i, QCryptoAkCipherMPI *mpi)
36*4c5e512eSLei He{
37*4c5e512eSLei He    if (asn1_der_iterator_next(i) != ASN1_ITERATOR_PRIMITIVE ||
38*4c5e512eSLei He        i->type != ASN1_INTEGER) {
39*4c5e512eSLei He        return false;
40*4c5e512eSLei He    }
41*4c5e512eSLei He    return DumpMPI(i, mpi);
42*4c5e512eSLei He}
43*4c5e512eSLei He
44*4c5e512eSLei He/**
45*4c5e512eSLei He *        RsaPrivKey ::= SEQUENCE {
46*4c5e512eSLei He *             version     INTEGER
47*4c5e512eSLei He *             n           INTEGER
48*4c5e512eSLei He *             e           INTEGER
49*4c5e512eSLei He *             d           INTEGER
50*4c5e512eSLei He *             p           INTEGER
51*4c5e512eSLei He *             q           INTEGER
52*4c5e512eSLei He *             dp          INTEGER
53*4c5e512eSLei He *             dq          INTEGER
54*4c5e512eSLei He *             u           INTEGER
55*4c5e512eSLei He *       otherPrimeInfos   OtherPrimeInfos OPTIONAL
56*4c5e512eSLei He *         }
57*4c5e512eSLei He */
58*4c5e512eSLei Hestatic QCryptoAkCipherRSAKey *qcrypto_nettle_rsa_private_key_parse(
59*4c5e512eSLei He    const uint8_t *key, size_t keylen, Error **errp)
60*4c5e512eSLei He{
61*4c5e512eSLei He    QCryptoAkCipherRSAKey *rsa = g_new0(QCryptoAkCipherRSAKey, 1);
62*4c5e512eSLei He    struct asn1_der_iterator i;
63*4c5e512eSLei He    uint32_t version;
64*4c5e512eSLei He    int tag;
65*4c5e512eSLei He
66*4c5e512eSLei He    /* Parse entire struct */
67*4c5e512eSLei He    if (asn1_der_iterator_first(&i, keylen, key) != ASN1_ITERATOR_CONSTRUCTED ||
68*4c5e512eSLei He        i.type != ASN1_SEQUENCE ||
69*4c5e512eSLei He        asn1_der_decode_constructed_last(&i) != ASN1_ITERATOR_PRIMITIVE ||
70*4c5e512eSLei He        i.type != ASN1_INTEGER ||
71*4c5e512eSLei He        !asn1_der_get_uint32(&i, &version) ||
72*4c5e512eSLei He        version > 1 ||
73*4c5e512eSLei He        !GetMPI(&i, &rsa->n) ||
74*4c5e512eSLei He        !GetMPI(&i, &rsa->e) ||
75*4c5e512eSLei He        !GetMPI(&i, &rsa->d) ||
76*4c5e512eSLei He        !GetMPI(&i, &rsa->p) ||
77*4c5e512eSLei He        !GetMPI(&i, &rsa->q) ||
78*4c5e512eSLei He        !GetMPI(&i, &rsa->dp) ||
79*4c5e512eSLei He        !GetMPI(&i, &rsa->dq) ||
80*4c5e512eSLei He        !GetMPI(&i, &rsa->u)) {
81*4c5e512eSLei He        goto error;
82*4c5e512eSLei He    }
83*4c5e512eSLei He
84*4c5e512eSLei He    if (version == 1) {
85*4c5e512eSLei He        tag = asn1_der_iterator_next(&i);
86*4c5e512eSLei He        /**
87*4c5e512eSLei He         * According to the standard otherPrimeInfos must be present for
88*4c5e512eSLei He         * version 1. There is no strict verification here, this is to be
89*4c5e512eSLei He         * compatible with the unit test of the kernel. TODO: remove this
90*4c5e512eSLei He         * until linux-kernel's unit-test is fixed;
91*4c5e512eSLei He         */
92*4c5e512eSLei He        if (tag == ASN1_ITERATOR_END) {
93*4c5e512eSLei He            return rsa;
94*4c5e512eSLei He        }
95*4c5e512eSLei He        if (tag != ASN1_ITERATOR_CONSTRUCTED ||
96*4c5e512eSLei He            i.type != ASN1_SEQUENCE) {
97*4c5e512eSLei He            goto error;
98*4c5e512eSLei He        }
99*4c5e512eSLei He    }
100*4c5e512eSLei He
101*4c5e512eSLei He    if (asn1_der_iterator_next(&i) != ASN1_ITERATOR_END) {
102*4c5e512eSLei He        goto error;
103*4c5e512eSLei He    }
104*4c5e512eSLei He
105*4c5e512eSLei He    return rsa;
106*4c5e512eSLei He
107*4c5e512eSLei Heerror:
108*4c5e512eSLei He    error_setg(errp, "Failed to parse RSA private key");
109*4c5e512eSLei He    qcrypto_akcipher_rsakey_free(rsa);
110*4c5e512eSLei He    return NULL;
111*4c5e512eSLei He}
112*4c5e512eSLei He
113*4c5e512eSLei He/**
114*4c5e512eSLei He *        RsaPubKey ::= SEQUENCE {
115*4c5e512eSLei He *             n           INTEGER
116*4c5e512eSLei He *             e           INTEGER
117*4c5e512eSLei He *         }
118*4c5e512eSLei He */
119*4c5e512eSLei Hestatic QCryptoAkCipherRSAKey *qcrypto_nettle_rsa_public_key_parse(
120*4c5e512eSLei He    const uint8_t *key, size_t keylen, Error **errp)
121*4c5e512eSLei He{
122*4c5e512eSLei He
123*4c5e512eSLei He    QCryptoAkCipherRSAKey *rsa = g_new0(QCryptoAkCipherRSAKey, 1);
124*4c5e512eSLei He    struct asn1_der_iterator i;
125*4c5e512eSLei He
126*4c5e512eSLei He    if (asn1_der_iterator_first(&i, keylen, key) != ASN1_ITERATOR_CONSTRUCTED ||
127*4c5e512eSLei He        i.type != ASN1_SEQUENCE ||
128*4c5e512eSLei He        asn1_der_decode_constructed_last(&i) != ASN1_ITERATOR_PRIMITIVE ||
129*4c5e512eSLei He        !DumpMPI(&i, &rsa->n) ||
130*4c5e512eSLei He        !GetMPI(&i, &rsa->e) ||
131*4c5e512eSLei He        asn1_der_iterator_next(&i) != ASN1_ITERATOR_END) {
132*4c5e512eSLei He        goto error;
133*4c5e512eSLei He    }
134*4c5e512eSLei He
135*4c5e512eSLei He    return rsa;
136*4c5e512eSLei He
137*4c5e512eSLei Heerror:
138*4c5e512eSLei He    error_setg(errp, "Failed to parse RSA public key");
139*4c5e512eSLei He    qcrypto_akcipher_rsakey_free(rsa);
140*4c5e512eSLei He    return NULL;
141*4c5e512eSLei He}
142*4c5e512eSLei He
143*4c5e512eSLei HeQCryptoAkCipherRSAKey *qcrypto_akcipher_rsakey_parse(
144*4c5e512eSLei He    QCryptoAkCipherKeyType type, const uint8_t *key,
145*4c5e512eSLei He    size_t keylen, Error **errp)
146*4c5e512eSLei He{
147*4c5e512eSLei He    switch (type) {
148*4c5e512eSLei He    case QCRYPTO_AKCIPHER_KEY_TYPE_PRIVATE:
149*4c5e512eSLei He        return qcrypto_nettle_rsa_private_key_parse(key, keylen, errp);
150*4c5e512eSLei He
151*4c5e512eSLei He    case QCRYPTO_AKCIPHER_KEY_TYPE_PUBLIC:
152*4c5e512eSLei He        return qcrypto_nettle_rsa_public_key_parse(key, keylen, errp);
153*4c5e512eSLei He
154*4c5e512eSLei He    default:
155*4c5e512eSLei He        error_setg(errp, "Unknown key type: %d", type);
156*4c5e512eSLei He        return NULL;
157*4c5e512eSLei He    }
158*4c5e512eSLei He}
159