qemu

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

rsakey-builtin.c.inc (6133B)


      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 "der.h"
     23 #include "rsakey.h"
     24 
     25 static int extract_mpi(void *ctx, const uint8_t *value,
     26                        size_t vlen, Error **errp)
     27 {
     28     QCryptoAkCipherMPI *mpi = (QCryptoAkCipherMPI *)ctx;
     29     if (vlen == 0) {
     30         error_setg(errp, "Empty mpi field");
     31         return -1;
     32     }
     33     mpi->data = g_memdup2(value, vlen);
     34     mpi->len = vlen;
     35     return 0;
     36 }
     37 
     38 static int extract_version(void *ctx, const uint8_t *value,
     39                            size_t vlen, Error **errp)
     40 {
     41     uint8_t *version = (uint8_t *)ctx;
     42     if (vlen != 1 || *value > 1) {
     43         error_setg(errp, "Invalid rsakey version");
     44         return -1;
     45     }
     46     *version = *value;
     47     return 0;
     48 }
     49 
     50 static int extract_seq_content(void *ctx, const uint8_t *value,
     51                                size_t vlen, Error **errp)
     52 {
     53     const uint8_t **content = (const uint8_t **)ctx;
     54     if (vlen == 0) {
     55         error_setg(errp, "Empty sequence");
     56         return -1;
     57     }
     58     *content = value;
     59     return 0;
     60 }
     61 
     62 /**
     63  *
     64  *        RsaPubKey ::= SEQUENCE {
     65  *             n           INTEGER
     66  *             e           INTEGER
     67  *         }
     68  */
     69 static QCryptoAkCipherRSAKey *qcrypto_builtin_rsa_public_key_parse(
     70     const uint8_t *key, size_t keylen, Error **errp)
     71 {
     72     QCryptoAkCipherRSAKey *rsa = g_new0(QCryptoAkCipherRSAKey, 1);
     73     const uint8_t *seq;
     74     size_t seq_length;
     75     int decode_ret;
     76 
     77     decode_ret = qcrypto_der_decode_seq(&key, &keylen,
     78                                         extract_seq_content, &seq, errp);
     79     if (decode_ret < 0 || keylen != 0) {
     80         goto error;
     81     }
     82     seq_length = decode_ret;
     83 
     84     if (qcrypto_der_decode_int(&seq, &seq_length, extract_mpi,
     85                                &rsa->n, errp) < 0 ||
     86         qcrypto_der_decode_int(&seq, &seq_length, extract_mpi,
     87                                &rsa->e, errp) < 0) {
     88         goto error;
     89     }
     90     if (seq_length != 0) {
     91         goto error;
     92     }
     93 
     94     return rsa;
     95 
     96 error:
     97     if (errp && !*errp) {
     98         error_setg(errp, "Invalid RSA public key");
     99     }
    100     qcrypto_akcipher_rsakey_free(rsa);
    101     return NULL;
    102 }
    103 
    104 /**
    105  *        RsaPrivKey ::= SEQUENCE {
    106  *             version     INTEGER
    107  *             n           INTEGER
    108  *             e           INTEGER
    109  *             d           INTEGER
    110  *             p           INTEGER
    111  *             q           INTEGER
    112  *             dp          INTEGER
    113  *             dq          INTEGER
    114  *             u           INTEGER
    115  *       otherPrimeInfos   OtherPrimeInfos OPTIONAL
    116  *         }
    117  */
    118 static QCryptoAkCipherRSAKey *qcrypto_builtin_rsa_private_key_parse(
    119     const uint8_t *key, size_t keylen, Error **errp)
    120 {
    121     QCryptoAkCipherRSAKey *rsa = g_new0(QCryptoAkCipherRSAKey, 1);
    122     uint8_t version;
    123     const uint8_t *seq;
    124     int decode_ret;
    125     size_t seq_length;
    126 
    127     decode_ret = qcrypto_der_decode_seq(&key, &keylen, extract_seq_content,
    128                                         &seq, errp);
    129     if (decode_ret < 0 || keylen != 0) {
    130         goto error;
    131     }
    132     seq_length = decode_ret;
    133 
    134     decode_ret = qcrypto_der_decode_int(&seq, &seq_length, extract_version,
    135                                         &version, errp);
    136 
    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,
    144                                errp) < 0 ||
    145         qcrypto_der_decode_int(&seq, &seq_length, extract_mpi, &rsa->q,
    146                                errp) < 0 ||
    147         qcrypto_der_decode_int(&seq, &seq_length, extract_mpi, &rsa->dp,
    148                                errp) < 0 ||
    149         qcrypto_der_decode_int(&seq, &seq_length, extract_mpi, &rsa->dq,
    150                                errp) < 0 ||
    151         qcrypto_der_decode_int(&seq, &seq_length, extract_mpi, &rsa->u,
    152                                errp) < 0) {
    153         goto error;
    154     }
    155 
    156     /**
    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.
    161      */
    162     if (version == 1 && seq_length != 0) {
    163         if (qcrypto_der_decode_seq(&seq, &seq_length, NULL, NULL, errp) < 0) {
    164             goto error;
    165         }
    166         if (seq_length != 0) {
    167             goto error;
    168         }
    169         return rsa;
    170     }
    171     if (seq_length != 0) {
    172         goto error;
    173     }
    174 
    175     return rsa;
    176 
    177 error:
    178     if (errp && !*errp) {
    179         error_setg(errp, "Invalid RSA private key");
    180     }
    181     qcrypto_akcipher_rsakey_free(rsa);
    182     return NULL;
    183 }
    184 
    185 QCryptoAkCipherRSAKey *qcrypto_akcipher_rsakey_parse(
    186     QCryptoAkCipherKeyType type, const uint8_t *key,
    187     size_t keylen, Error **errp)
    188 {
    189     switch (type) {
    190     case QCRYPTO_AKCIPHER_KEY_TYPE_PRIVATE:
    191         return qcrypto_builtin_rsa_private_key_parse(key, keylen, errp);
    192 
    193     case QCRYPTO_AKCIPHER_KEY_TYPE_PUBLIC:
    194         return qcrypto_builtin_rsa_public_key_parse(key, keylen, errp);
    195 
    196     default:
    197         error_setg(errp, "Unknown key type: %d", type);
    198         return NULL;
    199     }
    200 }