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 28static 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 35static 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 */ 58static 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 107error: 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 */ 119static 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 137error: 138 error_setg(errp, "Failed to parse RSA public key"); 139 qcrypto_akcipher_rsakey_free(rsa); 140 return NULL; 141} 142 143QCryptoAkCipherRSAKey *qcrypto_akcipher_rsakey_parse( 144 QCryptoAkCipherKeyType type, const uint8_t *key, 145 size_t keylen, Error **errp) 146{ 147 switch (type) { 148 case QCRYPTO_AK_CIPHER_KEY_TYPE_PRIVATE: 149 return qcrypto_nettle_rsa_private_key_parse(key, keylen, errp); 150 151 case QCRYPTO_AK_CIPHER_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} 159