1 /* 2 * QEMU Crypto ASN.1 DER decoder 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 "qemu/osdep.h" 23 #include "crypto/der.h" 24 25 typedef struct QCryptoDerEncodeNode { 26 uint8_t tag; 27 struct QCryptoDerEncodeNode *parent; 28 struct QCryptoDerEncodeNode *next; 29 /* for constructed type, data is null */ 30 const uint8_t *data; 31 size_t dlen; 32 } QCryptoDerEncodeNode; 33 34 typedef struct QCryptoEncodeContext { 35 QCryptoDerEncodeNode root; 36 QCryptoDerEncodeNode *current_parent; 37 QCryptoDerEncodeNode *tail; 38 } QCryptoEncodeContext; 39 40 enum QCryptoDERTypeTag { 41 QCRYPTO_DER_TYPE_TAG_BOOL = 0x1, 42 QCRYPTO_DER_TYPE_TAG_INT = 0x2, 43 QCRYPTO_DER_TYPE_TAG_BIT_STR = 0x3, 44 QCRYPTO_DER_TYPE_TAG_OCT_STR = 0x4, 45 QCRYPTO_DER_TYPE_TAG_NULL = 0x5, 46 QCRYPTO_DER_TYPE_TAG_OID = 0x6, 47 QCRYPTO_DER_TYPE_TAG_SEQ = 0x10, 48 QCRYPTO_DER_TYPE_TAG_SET = 0x11, 49 }; 50 51 enum QCryptoDERTagClass { 52 QCRYPTO_DER_TAG_CLASS_UNIV = 0x0, 53 QCRYPTO_DER_TAG_CLASS_APPL = 0x1, 54 QCRYPTO_DER_TAG_CLASS_CONT = 0x2, 55 QCRYPTO_DER_TAG_CLASS_PRIV = 0x3, 56 }; 57 58 enum QCryptoDERTagEnc { 59 QCRYPTO_DER_TAG_ENC_PRIM = 0x0, 60 QCRYPTO_DER_TAG_ENC_CONS = 0x1, 61 }; 62 63 #define QCRYPTO_DER_TAG_ENC_MASK 0x20 64 #define QCRYPTO_DER_TAG_ENC_SHIFT 5 65 66 #define QCRYPTO_DER_TAG_CLASS_MASK 0xc0 67 #define QCRYPTO_DER_TAG_CLASS_SHIFT 6 68 69 #define QCRYPTO_DER_TAG_VAL_MASK 0x1f 70 #define QCRYPTO_DER_SHORT_LEN_MASK 0x80 71 72 #define QCRYPTO_DER_TAG(class, enc, val) \ 73 (((class) << QCRYPTO_DER_TAG_CLASS_SHIFT) | \ 74 ((enc) << QCRYPTO_DER_TAG_ENC_SHIFT) | (val)) 75 76 /** 77 * qcrypto_der_encode_length: 78 * @src_len: the length of source data 79 * @dst: destination to save the encoded 'length', if dst is NULL, only compute 80 * the expected buffer size in bytes. 81 * @dst_len: output parameter, indicates how many bytes wrote. 82 * 83 * Encode the 'length' part of TLV tuple. 84 */ 85 static void qcrypto_der_encode_length(size_t src_len, 86 uint8_t *dst, size_t *dst_len) 87 { 88 size_t max_length = 0xFF; 89 uint8_t length_bytes = 0, header_byte; 90 91 if (src_len < QCRYPTO_DER_SHORT_LEN_MASK) { 92 header_byte = src_len; 93 *dst_len = 1; 94 } else { 95 for (length_bytes = 1; max_length < src_len; length_bytes++) { 96 max_length = (max_length << 8) + max_length; 97 } 98 header_byte = length_bytes; 99 header_byte |= QCRYPTO_DER_SHORT_LEN_MASK; 100 *dst_len = length_bytes + 1; 101 } 102 if (!dst) { 103 return; 104 } 105 *dst++ = header_byte; 106 /* Bigendian length bytes */ 107 for (; length_bytes > 0; length_bytes--) { 108 *dst++ = ((src_len >> (length_bytes - 1) * 8) & 0xFF); 109 } 110 } 111 112 static uint8_t qcrypto_der_peek_byte(const uint8_t **data, size_t *dlen) 113 { 114 return **data; 115 } 116 117 static void qcrypto_der_cut_nbytes(const uint8_t **data, 118 size_t *dlen, 119 size_t nbytes) 120 { 121 *data += nbytes; 122 *dlen -= nbytes; 123 } 124 125 static uint8_t qcrypto_der_cut_byte(const uint8_t **data, size_t *dlen) 126 { 127 uint8_t val = qcrypto_der_peek_byte(data, dlen); 128 129 qcrypto_der_cut_nbytes(data, dlen, 1); 130 131 return val; 132 } 133 134 static int qcrypto_der_invoke_callback(QCryptoDERDecodeCb cb, void *ctx, 135 const uint8_t *value, size_t vlen, 136 Error **errp) 137 { 138 if (!cb) { 139 return 0; 140 } 141 142 return cb(ctx, value, vlen, errp); 143 } 144 145 static int qcrypto_der_extract_definite_data(const uint8_t **data, size_t *dlen, 146 QCryptoDERDecodeCb cb, void *ctx, 147 Error **errp) 148 { 149 const uint8_t *value; 150 size_t vlen = 0; 151 uint8_t byte_count = qcrypto_der_cut_byte(data, dlen); 152 153 /* short format of definite-length */ 154 if (!(byte_count & QCRYPTO_DER_SHORT_LEN_MASK)) { 155 if (byte_count > *dlen) { 156 error_setg(errp, "Invalid content length: %u", byte_count); 157 return -1; 158 } 159 160 value = *data; 161 vlen = byte_count; 162 qcrypto_der_cut_nbytes(data, dlen, vlen); 163 164 if (qcrypto_der_invoke_callback(cb, ctx, value, vlen, errp) != 0) { 165 return -1; 166 } 167 return vlen; 168 } 169 170 /* Ignore highest bit */ 171 byte_count &= ~QCRYPTO_DER_SHORT_LEN_MASK; 172 173 /* 174 * size_t is enough to store the value of length, although the DER 175 * encoding standard supports larger length. 176 */ 177 if (byte_count > sizeof(size_t)) { 178 error_setg(errp, "Invalid byte count of content length: %u", 179 byte_count); 180 return -1; 181 } 182 183 if (byte_count > *dlen) { 184 error_setg(errp, "Invalid content length: %u", byte_count); 185 return -1; 186 } 187 while (byte_count--) { 188 vlen <<= 8; 189 vlen += qcrypto_der_cut_byte(data, dlen); 190 } 191 192 if (vlen > *dlen) { 193 error_setg(errp, "Invalid content length: %zu", vlen); 194 return -1; 195 } 196 197 value = *data; 198 qcrypto_der_cut_nbytes(data, dlen, vlen); 199 200 if (qcrypto_der_invoke_callback(cb, ctx, value, vlen, errp) != 0) { 201 return -1; 202 } 203 return vlen; 204 } 205 206 static int qcrypto_der_extract_data(const uint8_t **data, size_t *dlen, 207 QCryptoDERDecodeCb cb, void *ctx, 208 Error **errp) 209 { 210 uint8_t val; 211 if (*dlen < 1) { 212 error_setg(errp, "Need more data"); 213 return -1; 214 } 215 val = qcrypto_der_peek_byte(data, dlen); 216 217 /* must use definite length format */ 218 if (val == QCRYPTO_DER_SHORT_LEN_MASK) { 219 error_setg(errp, "Only definite length format is allowed"); 220 return -1; 221 } 222 223 return qcrypto_der_extract_definite_data(data, dlen, cb, ctx, errp); 224 } 225 226 static int qcrypto_der_decode_tlv(const uint8_t expected_tag, 227 const uint8_t **data, size_t *dlen, 228 QCryptoDERDecodeCb cb, 229 void *ctx, Error **errp) 230 { 231 const uint8_t *saved_data = *data; 232 size_t saved_dlen = *dlen; 233 uint8_t tag; 234 int data_length; 235 236 if (*dlen < 1) { 237 error_setg(errp, "Need more data"); 238 return -1; 239 } 240 tag = qcrypto_der_cut_byte(data, dlen); 241 if (tag != expected_tag) { 242 error_setg(errp, "Unexpected tag: expected: %u, actual: %u", 243 expected_tag, tag); 244 goto error; 245 } 246 247 data_length = qcrypto_der_extract_data(data, dlen, cb, ctx, errp); 248 if (data_length < 0) { 249 goto error; 250 } 251 return data_length; 252 253 error: 254 *data = saved_data; 255 *dlen = saved_dlen; 256 return -1; 257 } 258 259 int qcrypto_der_decode_int(const uint8_t **data, size_t *dlen, 260 QCryptoDERDecodeCb cb, void *ctx, Error **errp) 261 { 262 const uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, 263 QCRYPTO_DER_TAG_ENC_PRIM, 264 QCRYPTO_DER_TYPE_TAG_INT); 265 return qcrypto_der_decode_tlv(tag, data, dlen, cb, ctx, errp); 266 } 267 268 int qcrypto_der_decode_seq(const uint8_t **data, size_t *dlen, 269 QCryptoDERDecodeCb cb, void *ctx, Error **errp) 270 { 271 uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, 272 QCRYPTO_DER_TAG_ENC_CONS, 273 QCRYPTO_DER_TYPE_TAG_SEQ); 274 return qcrypto_der_decode_tlv(tag, data, dlen, cb, ctx, errp); 275 } 276 277 int qcrypto_der_decode_octet_str(const uint8_t **data, size_t *dlen, 278 QCryptoDERDecodeCb cb, void *ctx, Error **errp) 279 { 280 uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, 281 QCRYPTO_DER_TAG_ENC_PRIM, 282 QCRYPTO_DER_TYPE_TAG_OCT_STR); 283 return qcrypto_der_decode_tlv(tag, data, dlen, cb, ctx, errp); 284 } 285 286 int qcrypto_der_decode_bit_str(const uint8_t **data, size_t *dlen, 287 QCryptoDERDecodeCb cb, void *ctx, Error **errp) 288 { 289 uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, 290 QCRYPTO_DER_TAG_ENC_PRIM, 291 QCRYPTO_DER_TYPE_TAG_BIT_STR); 292 return qcrypto_der_decode_tlv(tag, data, dlen, cb, ctx, errp); 293 } 294 295 int qcrypto_der_decode_oid(const uint8_t **data, size_t *dlen, 296 QCryptoDERDecodeCb cb, void *ctx, Error **errp) 297 { 298 uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, 299 QCRYPTO_DER_TAG_ENC_PRIM, 300 QCRYPTO_DER_TYPE_TAG_OID); 301 return qcrypto_der_decode_tlv(tag, data, dlen, cb, ctx, errp); 302 } 303 304 int qcrypto_der_decode_ctx_tag(const uint8_t **data, size_t *dlen, int tag_id, 305 QCryptoDERDecodeCb cb, void *ctx, Error **errp) 306 { 307 uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_CONT, 308 QCRYPTO_DER_TAG_ENC_CONS, 309 tag_id); 310 return qcrypto_der_decode_tlv(tag, data, dlen, cb, ctx, errp); 311 } 312 313 static void qcrypto_der_encode_prim(QCryptoEncodeContext *ctx, uint8_t tag, 314 const uint8_t *data, size_t dlen) 315 { 316 QCryptoDerEncodeNode *node = g_new0(QCryptoDerEncodeNode, 1); 317 size_t nbytes_len; 318 319 node->tag = tag; 320 node->data = data; 321 node->dlen = dlen; 322 node->parent = ctx->current_parent; 323 324 qcrypto_der_encode_length(dlen, NULL, &nbytes_len); 325 /* 1 byte for Tag, nbyte_len for Length, and dlen for Value */ 326 node->parent->dlen += 1 + nbytes_len + dlen; 327 328 ctx->tail->next = node; 329 ctx->tail = node; 330 } 331 332 QCryptoEncodeContext *qcrypto_der_encode_ctx_new(void) 333 { 334 QCryptoEncodeContext *ctx = g_new0(QCryptoEncodeContext, 1); 335 ctx->current_parent = &ctx->root; 336 ctx->tail = &ctx->root; 337 return ctx; 338 } 339 340 static void qcrypto_der_encode_cons_begin(QCryptoEncodeContext *ctx, 341 uint8_t tag) 342 { 343 QCryptoDerEncodeNode *node = g_new0(QCryptoDerEncodeNode, 1); 344 345 node->tag = tag; 346 node->parent = ctx->current_parent; 347 ctx->current_parent = node; 348 ctx->tail->next = node; 349 ctx->tail = node; 350 } 351 352 static void qcrypto_der_encode_cons_end(QCryptoEncodeContext *ctx) 353 { 354 QCryptoDerEncodeNode *cons_node = ctx->current_parent; 355 size_t nbytes_len; 356 357 qcrypto_der_encode_length(cons_node->dlen, NULL, &nbytes_len); 358 /* 1 byte for Tag, nbyte_len for Length, and dlen for Value */ 359 cons_node->parent->dlen += 1 + nbytes_len + cons_node->dlen; 360 ctx->current_parent = cons_node->parent; 361 } 362 363 void qcrypto_der_encode_seq_begin(QCryptoEncodeContext *ctx) 364 { 365 uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, 366 QCRYPTO_DER_TAG_ENC_CONS, 367 QCRYPTO_DER_TYPE_TAG_SEQ); 368 qcrypto_der_encode_cons_begin(ctx, tag); 369 } 370 371 void qcrypto_der_encode_seq_end(QCryptoEncodeContext *ctx) 372 { 373 qcrypto_der_encode_cons_end(ctx); 374 } 375 376 void qcrypto_der_encode_oid(QCryptoEncodeContext *ctx, 377 const uint8_t *src, size_t src_len) 378 { 379 uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, 380 QCRYPTO_DER_TAG_ENC_PRIM, 381 QCRYPTO_DER_TYPE_TAG_OID); 382 qcrypto_der_encode_prim(ctx, tag, src, src_len); 383 } 384 385 void qcrypto_der_encode_int(QCryptoEncodeContext *ctx, 386 const uint8_t *src, size_t src_len) 387 { 388 uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, 389 QCRYPTO_DER_TAG_ENC_PRIM, 390 QCRYPTO_DER_TYPE_TAG_INT); 391 qcrypto_der_encode_prim(ctx, tag, src, src_len); 392 } 393 394 void qcrypto_der_encode_null(QCryptoEncodeContext *ctx) 395 { 396 uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, 397 QCRYPTO_DER_TAG_ENC_PRIM, 398 QCRYPTO_DER_TYPE_TAG_NULL); 399 qcrypto_der_encode_prim(ctx, tag, NULL, 0); 400 } 401 402 void qcrypto_der_encode_octet_str(QCryptoEncodeContext *ctx, 403 const uint8_t *src, size_t src_len) 404 { 405 uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, 406 QCRYPTO_DER_TAG_ENC_PRIM, 407 QCRYPTO_DER_TYPE_TAG_OCT_STR); 408 qcrypto_der_encode_prim(ctx, tag, src, src_len); 409 } 410 411 size_t qcrypto_der_encode_ctx_buffer_len(QCryptoEncodeContext *ctx) 412 { 413 return ctx->root.dlen; 414 } 415 416 void qcrypto_der_encode_ctx_flush_and_free(QCryptoEncodeContext *ctx, 417 uint8_t *dst) 418 { 419 QCryptoDerEncodeNode *node, *prev; 420 size_t len; 421 422 for (prev = &ctx->root; 423 (node = prev->next) && (prev->next = node->next, 1);) { 424 /* Tag */ 425 *dst++ = node->tag; 426 427 /* Length */ 428 qcrypto_der_encode_length(node->dlen, dst, &len); 429 dst += len; 430 431 /* Value */ 432 if (node->data) { 433 memcpy(dst, node->data, node->dlen); 434 dst += node->dlen; 435 } 436 g_free(node); 437 } 438 g_free(ctx); 439 } 440