14c5e512eSLei He/* 24c5e512eSLei He * QEMU Crypto akcipher algorithms 34c5e512eSLei He * 44c5e512eSLei He * Copyright (c) 2022 Bytedance 54c5e512eSLei He * Author: lei he <helei.sig11@bytedance.com> 64c5e512eSLei He * 74c5e512eSLei He * This library is free software; you can redistribute it and/or 84c5e512eSLei He * modify it under the terms of the GNU Lesser General Public 94c5e512eSLei He * License as published by the Free Software Foundation; either 104c5e512eSLei He * version 2.1 of the License, or (at your option) any later version. 114c5e512eSLei He * 124c5e512eSLei He * This library is distributed in the hope that it will be useful, 134c5e512eSLei He * but WITHOUT ANY WARRANTY; without even the implied warranty of 144c5e512eSLei He * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 154c5e512eSLei He * Lesser General Public License for more details. 164c5e512eSLei He * 174c5e512eSLei He * You should have received a copy of the GNU Lesser General Public 184c5e512eSLei He * License along with this library; if not, see <http://www.gnu.org/licenses/>. 194c5e512eSLei He * 204c5e512eSLei He */ 214c5e512eSLei He 224c5e512eSLei He#include <nettle/asn1.h> 234c5e512eSLei He 244c5e512eSLei He#include "qemu/osdep.h" 254c5e512eSLei He#include "qapi/error.h" 264c5e512eSLei He#include "rsakey.h" 274c5e512eSLei He 284c5e512eSLei Hestatic bool DumpMPI(struct asn1_der_iterator *i, QCryptoAkCipherMPI *mpi) 294c5e512eSLei He{ 304c5e512eSLei He mpi->data = g_memdup2(i->data, i->length); 314c5e512eSLei He mpi->len = i->length; 324c5e512eSLei He return true; 334c5e512eSLei He} 344c5e512eSLei He 354c5e512eSLei Hestatic bool GetMPI(struct asn1_der_iterator *i, QCryptoAkCipherMPI *mpi) 364c5e512eSLei He{ 374c5e512eSLei He if (asn1_der_iterator_next(i) != ASN1_ITERATOR_PRIMITIVE || 384c5e512eSLei He i->type != ASN1_INTEGER) { 394c5e512eSLei He return false; 404c5e512eSLei He } 414c5e512eSLei He return DumpMPI(i, mpi); 424c5e512eSLei He} 434c5e512eSLei He 444c5e512eSLei He/** 454c5e512eSLei He * RsaPrivKey ::= SEQUENCE { 464c5e512eSLei He * version INTEGER 474c5e512eSLei He * n INTEGER 484c5e512eSLei He * e INTEGER 494c5e512eSLei He * d INTEGER 504c5e512eSLei He * p INTEGER 514c5e512eSLei He * q INTEGER 524c5e512eSLei He * dp INTEGER 534c5e512eSLei He * dq INTEGER 544c5e512eSLei He * u INTEGER 554c5e512eSLei He * otherPrimeInfos OtherPrimeInfos OPTIONAL 564c5e512eSLei He * } 574c5e512eSLei He */ 584c5e512eSLei Hestatic QCryptoAkCipherRSAKey *qcrypto_nettle_rsa_private_key_parse( 594c5e512eSLei He const uint8_t *key, size_t keylen, Error **errp) 604c5e512eSLei He{ 614c5e512eSLei He QCryptoAkCipherRSAKey *rsa = g_new0(QCryptoAkCipherRSAKey, 1); 624c5e512eSLei He struct asn1_der_iterator i; 634c5e512eSLei He uint32_t version; 644c5e512eSLei He int tag; 654c5e512eSLei He 664c5e512eSLei He /* Parse entire struct */ 674c5e512eSLei He if (asn1_der_iterator_first(&i, keylen, key) != ASN1_ITERATOR_CONSTRUCTED || 684c5e512eSLei He i.type != ASN1_SEQUENCE || 694c5e512eSLei He asn1_der_decode_constructed_last(&i) != ASN1_ITERATOR_PRIMITIVE || 704c5e512eSLei He i.type != ASN1_INTEGER || 714c5e512eSLei He !asn1_der_get_uint32(&i, &version) || 724c5e512eSLei He version > 1 || 734c5e512eSLei He !GetMPI(&i, &rsa->n) || 744c5e512eSLei He !GetMPI(&i, &rsa->e) || 754c5e512eSLei He !GetMPI(&i, &rsa->d) || 764c5e512eSLei He !GetMPI(&i, &rsa->p) || 774c5e512eSLei He !GetMPI(&i, &rsa->q) || 784c5e512eSLei He !GetMPI(&i, &rsa->dp) || 794c5e512eSLei He !GetMPI(&i, &rsa->dq) || 804c5e512eSLei He !GetMPI(&i, &rsa->u)) { 814c5e512eSLei He goto error; 824c5e512eSLei He } 834c5e512eSLei He 844c5e512eSLei He if (version == 1) { 854c5e512eSLei He tag = asn1_der_iterator_next(&i); 864c5e512eSLei He /** 874c5e512eSLei He * According to the standard otherPrimeInfos must be present for 884c5e512eSLei He * version 1. There is no strict verification here, this is to be 894c5e512eSLei He * compatible with the unit test of the kernel. TODO: remove this 904c5e512eSLei He * until linux-kernel's unit-test is fixed; 914c5e512eSLei He */ 924c5e512eSLei He if (tag == ASN1_ITERATOR_END) { 934c5e512eSLei He return rsa; 944c5e512eSLei He } 954c5e512eSLei He if (tag != ASN1_ITERATOR_CONSTRUCTED || 964c5e512eSLei He i.type != ASN1_SEQUENCE) { 974c5e512eSLei He goto error; 984c5e512eSLei He } 994c5e512eSLei He } 1004c5e512eSLei He 1014c5e512eSLei He if (asn1_der_iterator_next(&i) != ASN1_ITERATOR_END) { 1024c5e512eSLei He goto error; 1034c5e512eSLei He } 1044c5e512eSLei He 1054c5e512eSLei He return rsa; 1064c5e512eSLei He 1074c5e512eSLei Heerror: 1084c5e512eSLei He error_setg(errp, "Failed to parse RSA private key"); 1094c5e512eSLei He qcrypto_akcipher_rsakey_free(rsa); 1104c5e512eSLei He return NULL; 1114c5e512eSLei He} 1124c5e512eSLei He 1134c5e512eSLei He/** 1144c5e512eSLei He * RsaPubKey ::= SEQUENCE { 1154c5e512eSLei He * n INTEGER 1164c5e512eSLei He * e INTEGER 1174c5e512eSLei He * } 1184c5e512eSLei He */ 1194c5e512eSLei Hestatic QCryptoAkCipherRSAKey *qcrypto_nettle_rsa_public_key_parse( 1204c5e512eSLei He const uint8_t *key, size_t keylen, Error **errp) 1214c5e512eSLei He{ 1224c5e512eSLei He 1234c5e512eSLei He QCryptoAkCipherRSAKey *rsa = g_new0(QCryptoAkCipherRSAKey, 1); 1244c5e512eSLei He struct asn1_der_iterator i; 1254c5e512eSLei He 1264c5e512eSLei He if (asn1_der_iterator_first(&i, keylen, key) != ASN1_ITERATOR_CONSTRUCTED || 1274c5e512eSLei He i.type != ASN1_SEQUENCE || 1284c5e512eSLei He asn1_der_decode_constructed_last(&i) != ASN1_ITERATOR_PRIMITIVE || 1294c5e512eSLei He !DumpMPI(&i, &rsa->n) || 1304c5e512eSLei He !GetMPI(&i, &rsa->e) || 1314c5e512eSLei He asn1_der_iterator_next(&i) != ASN1_ITERATOR_END) { 1324c5e512eSLei He goto error; 1334c5e512eSLei He } 1344c5e512eSLei He 1354c5e512eSLei He return rsa; 1364c5e512eSLei He 1374c5e512eSLei Heerror: 1384c5e512eSLei He error_setg(errp, "Failed to parse RSA public key"); 1394c5e512eSLei He qcrypto_akcipher_rsakey_free(rsa); 1404c5e512eSLei He return NULL; 1414c5e512eSLei He} 1424c5e512eSLei He 1434c5e512eSLei HeQCryptoAkCipherRSAKey *qcrypto_akcipher_rsakey_parse( 1444c5e512eSLei He QCryptoAkCipherKeyType type, const uint8_t *key, 1454c5e512eSLei He size_t keylen, Error **errp) 1464c5e512eSLei He{ 1474c5e512eSLei He switch (type) { 148*5f4059efSMarkus Armbruster case QCRYPTO_AK_CIPHER_KEY_TYPE_PRIVATE: 1494c5e512eSLei He return qcrypto_nettle_rsa_private_key_parse(key, keylen, errp); 1504c5e512eSLei He 151*5f4059efSMarkus Armbruster case QCRYPTO_AK_CIPHER_KEY_TYPE_PUBLIC: 1524c5e512eSLei He return qcrypto_nettle_rsa_public_key_parse(key, keylen, errp); 1534c5e512eSLei He 1544c5e512eSLei He default: 1554c5e512eSLei He error_setg(errp, "Unknown key type: %d", type); 1564c5e512eSLei He return NULL; 1574c5e512eSLei He } 1584c5e512eSLei He} 159