qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

rsakey-nettle.c.inc (4699B)


      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 
     22 #include <nettle/asn1.h>
     23 
     24 #include "qemu/osdep.h"
     25 #include "qapi/error.h"
     26 #include "rsakey.h"
     27 
     28 static bool DumpMPI(struct asn1_der_iterator *i, QCryptoAkCipherMPI *mpi)
     29 {
     30     mpi->data = g_memdup2(i->data, i->length);
     31     mpi->len = i->length;
     32     return true;
     33 }
     34 
     35 static bool GetMPI(struct asn1_der_iterator *i, QCryptoAkCipherMPI *mpi)
     36 {
     37     if (asn1_der_iterator_next(i) != ASN1_ITERATOR_PRIMITIVE ||
     38         i->type != ASN1_INTEGER) {
     39         return false;
     40     }
     41     return DumpMPI(i, mpi);
     42 }
     43 
     44 /**
     45  *        RsaPrivKey ::= SEQUENCE {
     46  *             version     INTEGER
     47  *             n           INTEGER
     48  *             e           INTEGER
     49  *             d           INTEGER
     50  *             p           INTEGER
     51  *             q           INTEGER
     52  *             dp          INTEGER
     53  *             dq          INTEGER
     54  *             u           INTEGER
     55  *       otherPrimeInfos   OtherPrimeInfos OPTIONAL
     56  *         }
     57  */
     58 static QCryptoAkCipherRSAKey *qcrypto_nettle_rsa_private_key_parse(
     59     const uint8_t *key, size_t keylen, Error **errp)
     60 {
     61     QCryptoAkCipherRSAKey *rsa = g_new0(QCryptoAkCipherRSAKey, 1);
     62     struct asn1_der_iterator i;
     63     uint32_t version;
     64     int tag;
     65 
     66     /* Parse entire struct */
     67     if (asn1_der_iterator_first(&i, keylen, key) != ASN1_ITERATOR_CONSTRUCTED ||
     68         i.type != ASN1_SEQUENCE ||
     69         asn1_der_decode_constructed_last(&i) != ASN1_ITERATOR_PRIMITIVE ||
     70         i.type != ASN1_INTEGER ||
     71         !asn1_der_get_uint32(&i, &version) ||
     72         version > 1 ||
     73         !GetMPI(&i, &rsa->n) ||
     74         !GetMPI(&i, &rsa->e) ||
     75         !GetMPI(&i, &rsa->d) ||
     76         !GetMPI(&i, &rsa->p) ||
     77         !GetMPI(&i, &rsa->q) ||
     78         !GetMPI(&i, &rsa->dp) ||
     79         !GetMPI(&i, &rsa->dq) ||
     80         !GetMPI(&i, &rsa->u)) {
     81         goto error;
     82     }
     83 
     84     if (version == 1) {
     85         tag = asn1_der_iterator_next(&i);
     86         /**
     87          * According to the standard otherPrimeInfos must be present for
     88          * version 1. There is no strict verification here, this is to be
     89          * compatible with the unit test of the kernel. TODO: remove this
     90          * until linux-kernel's unit-test is fixed;
     91          */
     92         if (tag == ASN1_ITERATOR_END) {
     93             return rsa;
     94         }
     95         if (tag != ASN1_ITERATOR_CONSTRUCTED ||
     96             i.type != ASN1_SEQUENCE) {
     97             goto error;
     98         }
     99     }
    100 
    101     if (asn1_der_iterator_next(&i) != ASN1_ITERATOR_END) {
    102         goto error;
    103     }
    104 
    105     return rsa;
    106 
    107 error:
    108     error_setg(errp, "Failed to parse RSA private key");
    109     qcrypto_akcipher_rsakey_free(rsa);
    110     return NULL;
    111 }
    112 
    113 /**
    114  *        RsaPubKey ::= SEQUENCE {
    115  *             n           INTEGER
    116  *             e           INTEGER
    117  *         }
    118  */
    119 static QCryptoAkCipherRSAKey *qcrypto_nettle_rsa_public_key_parse(
    120     const uint8_t *key, size_t keylen, Error **errp)
    121 {
    122 
    123     QCryptoAkCipherRSAKey *rsa = g_new0(QCryptoAkCipherRSAKey, 1);
    124     struct asn1_der_iterator i;
    125 
    126     if (asn1_der_iterator_first(&i, keylen, key) != ASN1_ITERATOR_CONSTRUCTED ||
    127         i.type != ASN1_SEQUENCE ||
    128         asn1_der_decode_constructed_last(&i) != ASN1_ITERATOR_PRIMITIVE ||
    129         !DumpMPI(&i, &rsa->n) ||
    130         !GetMPI(&i, &rsa->e) ||
    131         asn1_der_iterator_next(&i) != ASN1_ITERATOR_END) {
    132         goto error;
    133     }
    134 
    135     return rsa;
    136 
    137 error:
    138     error_setg(errp, "Failed to parse RSA public key");
    139     qcrypto_akcipher_rsakey_free(rsa);
    140     return NULL;
    141 }
    142 
    143 QCryptoAkCipherRSAKey *qcrypto_akcipher_rsakey_parse(
    144     QCryptoAkCipherKeyType type, const uint8_t *key,
    145     size_t keylen, Error **errp)
    146 {
    147     switch (type) {
    148     case QCRYPTO_AKCIPHER_KEY_TYPE_PRIVATE:
    149         return qcrypto_nettle_rsa_private_key_parse(key, keylen, errp);
    150 
    151     case QCRYPTO_AKCIPHER_KEY_TYPE_PUBLIC:
    152         return qcrypto_nettle_rsa_public_key_parse(key, keylen, errp);
    153 
    154     default:
    155         error_setg(errp, "Unknown key type: %d", type);
    156         return NULL;
    157     }
    158 }