1*99d423f1SLei He /* 2*99d423f1SLei He * QEMU Crypto ASN.1 DER decoder 3*99d423f1SLei He * 4*99d423f1SLei He * Copyright (c) 2022 Bytedance 5*99d423f1SLei He * Author: lei he <helei.sig11@bytedance.com> 6*99d423f1SLei He * 7*99d423f1SLei He * This library is free software; you can redistribute it and/or 8*99d423f1SLei He * modify it under the terms of the GNU Lesser General Public 9*99d423f1SLei He * License as published by the Free Software Foundation; either 10*99d423f1SLei He * version 2.1 of the License, or (at your option) any later version. 11*99d423f1SLei He * 12*99d423f1SLei He * This library is distributed in the hope that it will be useful, 13*99d423f1SLei He * but WITHOUT ANY WARRANTY; without even the implied warranty of 14*99d423f1SLei He * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15*99d423f1SLei He * Lesser General Public License for more details. 16*99d423f1SLei He * 17*99d423f1SLei He * You should have received a copy of the GNU Lesser General Public 18*99d423f1SLei He * License along with this library; if not, see <http://www.gnu.org/licenses/>. 19*99d423f1SLei He * 20*99d423f1SLei He */ 21*99d423f1SLei He 22*99d423f1SLei He #include "qemu/osdep.h" 23*99d423f1SLei He #include "crypto/der.h" 24*99d423f1SLei He 25*99d423f1SLei He enum QCryptoDERTypeTag { 26*99d423f1SLei He QCRYPTO_DER_TYPE_TAG_BOOL = 0x1, 27*99d423f1SLei He QCRYPTO_DER_TYPE_TAG_INT = 0x2, 28*99d423f1SLei He QCRYPTO_DER_TYPE_TAG_BIT_STR = 0x3, 29*99d423f1SLei He QCRYPTO_DER_TYPE_TAG_OCT_STR = 0x4, 30*99d423f1SLei He QCRYPTO_DER_TYPE_TAG_OCT_NULL = 0x5, 31*99d423f1SLei He QCRYPTO_DER_TYPE_TAG_OCT_OID = 0x6, 32*99d423f1SLei He QCRYPTO_DER_TYPE_TAG_SEQ = 0x10, 33*99d423f1SLei He QCRYPTO_DER_TYPE_TAG_SET = 0x11, 34*99d423f1SLei He }; 35*99d423f1SLei He 36*99d423f1SLei He #define QCRYPTO_DER_CONSTRUCTED_MASK 0x20 37*99d423f1SLei He #define QCRYPTO_DER_SHORT_LEN_MASK 0x80 38*99d423f1SLei He 39*99d423f1SLei He static uint8_t qcrypto_der_peek_byte(const uint8_t **data, size_t *dlen) 40*99d423f1SLei He { 41*99d423f1SLei He return **data; 42*99d423f1SLei He } 43*99d423f1SLei He 44*99d423f1SLei He static void qcrypto_der_cut_nbytes(const uint8_t **data, 45*99d423f1SLei He size_t *dlen, 46*99d423f1SLei He size_t nbytes) 47*99d423f1SLei He { 48*99d423f1SLei He *data += nbytes; 49*99d423f1SLei He *dlen -= nbytes; 50*99d423f1SLei He } 51*99d423f1SLei He 52*99d423f1SLei He static uint8_t qcrypto_der_cut_byte(const uint8_t **data, size_t *dlen) 53*99d423f1SLei He { 54*99d423f1SLei He uint8_t val = qcrypto_der_peek_byte(data, dlen); 55*99d423f1SLei He 56*99d423f1SLei He qcrypto_der_cut_nbytes(data, dlen, 1); 57*99d423f1SLei He 58*99d423f1SLei He return val; 59*99d423f1SLei He } 60*99d423f1SLei He 61*99d423f1SLei He static int qcrypto_der_invoke_callback(QCryptoDERDecodeCb cb, void *ctx, 62*99d423f1SLei He const uint8_t *value, size_t vlen, 63*99d423f1SLei He Error **errp) 64*99d423f1SLei He { 65*99d423f1SLei He if (!cb) { 66*99d423f1SLei He return 0; 67*99d423f1SLei He } 68*99d423f1SLei He 69*99d423f1SLei He return cb(ctx, value, vlen, errp); 70*99d423f1SLei He } 71*99d423f1SLei He 72*99d423f1SLei He static int qcrypto_der_extract_definite_data(const uint8_t **data, size_t *dlen, 73*99d423f1SLei He QCryptoDERDecodeCb cb, void *ctx, 74*99d423f1SLei He Error **errp) 75*99d423f1SLei He { 76*99d423f1SLei He const uint8_t *value; 77*99d423f1SLei He size_t vlen = 0; 78*99d423f1SLei He uint8_t byte_count = qcrypto_der_cut_byte(data, dlen); 79*99d423f1SLei He 80*99d423f1SLei He /* short format of definite-length */ 81*99d423f1SLei He if (!(byte_count & QCRYPTO_DER_SHORT_LEN_MASK)) { 82*99d423f1SLei He if (byte_count > *dlen) { 83*99d423f1SLei He error_setg(errp, "Invalid content length: %u", byte_count); 84*99d423f1SLei He return -1; 85*99d423f1SLei He } 86*99d423f1SLei He 87*99d423f1SLei He value = *data; 88*99d423f1SLei He vlen = byte_count; 89*99d423f1SLei He qcrypto_der_cut_nbytes(data, dlen, vlen); 90*99d423f1SLei He 91*99d423f1SLei He if (qcrypto_der_invoke_callback(cb, ctx, value, vlen, errp) != 0) { 92*99d423f1SLei He return -1; 93*99d423f1SLei He } 94*99d423f1SLei He return vlen; 95*99d423f1SLei He } 96*99d423f1SLei He 97*99d423f1SLei He /* Ignore highest bit */ 98*99d423f1SLei He byte_count &= ~QCRYPTO_DER_SHORT_LEN_MASK; 99*99d423f1SLei He 100*99d423f1SLei He /* 101*99d423f1SLei He * size_t is enough to store the value of length, although the DER 102*99d423f1SLei He * encoding standard supports larger length. 103*99d423f1SLei He */ 104*99d423f1SLei He if (byte_count > sizeof(size_t)) { 105*99d423f1SLei He error_setg(errp, "Invalid byte count of content length: %u", 106*99d423f1SLei He byte_count); 107*99d423f1SLei He return -1; 108*99d423f1SLei He } 109*99d423f1SLei He 110*99d423f1SLei He if (byte_count > *dlen) { 111*99d423f1SLei He error_setg(errp, "Invalid content length: %u", byte_count); 112*99d423f1SLei He return -1; 113*99d423f1SLei He } 114*99d423f1SLei He while (byte_count--) { 115*99d423f1SLei He vlen <<= 8; 116*99d423f1SLei He vlen += qcrypto_der_cut_byte(data, dlen); 117*99d423f1SLei He } 118*99d423f1SLei He 119*99d423f1SLei He if (vlen > *dlen) { 120*99d423f1SLei He error_setg(errp, "Invalid content length: %zu", vlen); 121*99d423f1SLei He return -1; 122*99d423f1SLei He } 123*99d423f1SLei He 124*99d423f1SLei He value = *data; 125*99d423f1SLei He qcrypto_der_cut_nbytes(data, dlen, vlen); 126*99d423f1SLei He 127*99d423f1SLei He if (qcrypto_der_invoke_callback(cb, ctx, value, vlen, errp) != 0) { 128*99d423f1SLei He return -1; 129*99d423f1SLei He } 130*99d423f1SLei He return vlen; 131*99d423f1SLei He } 132*99d423f1SLei He 133*99d423f1SLei He static int qcrypto_der_extract_data(const uint8_t **data, size_t *dlen, 134*99d423f1SLei He QCryptoDERDecodeCb cb, void *ctx, 135*99d423f1SLei He Error **errp) 136*99d423f1SLei He { 137*99d423f1SLei He uint8_t val; 138*99d423f1SLei He if (*dlen < 1) { 139*99d423f1SLei He error_setg(errp, "Need more data"); 140*99d423f1SLei He return -1; 141*99d423f1SLei He } 142*99d423f1SLei He val = qcrypto_der_peek_byte(data, dlen); 143*99d423f1SLei He 144*99d423f1SLei He /* must use definite length format */ 145*99d423f1SLei He if (val == QCRYPTO_DER_SHORT_LEN_MASK) { 146*99d423f1SLei He error_setg(errp, "Only definite length format is allowed"); 147*99d423f1SLei He return -1; 148*99d423f1SLei He } 149*99d423f1SLei He 150*99d423f1SLei He return qcrypto_der_extract_definite_data(data, dlen, cb, ctx, errp); 151*99d423f1SLei He } 152*99d423f1SLei He 153*99d423f1SLei He int qcrypto_der_decode_int(const uint8_t **data, size_t *dlen, 154*99d423f1SLei He QCryptoDERDecodeCb cb, void *ctx, Error **errp) 155*99d423f1SLei He { 156*99d423f1SLei He uint8_t tag; 157*99d423f1SLei He if (*dlen < 1) { 158*99d423f1SLei He error_setg(errp, "Need more data"); 159*99d423f1SLei He return -1; 160*99d423f1SLei He } 161*99d423f1SLei He tag = qcrypto_der_cut_byte(data, dlen); 162*99d423f1SLei He 163*99d423f1SLei He /* INTEGER must encoded in primitive-form */ 164*99d423f1SLei He if (tag != QCRYPTO_DER_TYPE_TAG_INT) { 165*99d423f1SLei He error_setg(errp, "Invalid integer type tag: %u", tag); 166*99d423f1SLei He return -1; 167*99d423f1SLei He } 168*99d423f1SLei He 169*99d423f1SLei He return qcrypto_der_extract_data(data, dlen, cb, ctx, errp); 170*99d423f1SLei He } 171*99d423f1SLei He 172*99d423f1SLei He int qcrypto_der_decode_seq(const uint8_t **data, size_t *dlen, 173*99d423f1SLei He QCryptoDERDecodeCb cb, void *ctx, Error **errp) 174*99d423f1SLei He { 175*99d423f1SLei He uint8_t tag; 176*99d423f1SLei He if (*dlen < 1) { 177*99d423f1SLei He error_setg(errp, "Need more data"); 178*99d423f1SLei He return -1; 179*99d423f1SLei He } 180*99d423f1SLei He tag = qcrypto_der_cut_byte(data, dlen); 181*99d423f1SLei He 182*99d423f1SLei He /* SEQUENCE must use constructed form */ 183*99d423f1SLei He if (tag != (QCRYPTO_DER_TYPE_TAG_SEQ | QCRYPTO_DER_CONSTRUCTED_MASK)) { 184*99d423f1SLei He error_setg(errp, "Invalid type sequence tag: %u", tag); 185*99d423f1SLei He return -1; 186*99d423f1SLei He } 187*99d423f1SLei He 188*99d423f1SLei He return qcrypto_der_extract_data(data, dlen, cb, ctx, errp); 189*99d423f1SLei He } 190