xref: /openbmc/qemu/crypto/der.h (revision 0a19d879)
199d423f1SLei He /*
299d423f1SLei He  * Copyright (c) 2022 Bytedance
399d423f1SLei He  * Author: lei he <helei.sig11@bytedance.com>
499d423f1SLei He  *
599d423f1SLei He  * This library is free software; you can redistribute it and/or
699d423f1SLei He  * modify it under the terms of the GNU Lesser General Public
799d423f1SLei He  * License as published by the Free Software Foundation; either
899d423f1SLei He  * version 2.1 of the License, or (at your option) any later version.
999d423f1SLei He  *
1099d423f1SLei He  * This library is distributed in the hope that it will be useful,
1199d423f1SLei He  * but WITHOUT ANY WARRANTY; without even the implied warranty of
1299d423f1SLei He  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1399d423f1SLei He  * Lesser General Public License for more details.
1499d423f1SLei He  *
1599d423f1SLei He  * You should have received a copy of the GNU Lesser General Public
1699d423f1SLei He  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
1799d423f1SLei He  *
1899d423f1SLei He  */
1999d423f1SLei He 
2099d423f1SLei He #ifndef QCRYPTO_ASN1_DECODER_H
2199d423f1SLei He #define QCRYPTO_ASN1_DECODER_H
2299d423f1SLei He 
2399d423f1SLei He #include "qapi/error.h"
2499d423f1SLei He 
253b34ccadSLei He typedef struct QCryptoEncodeContext QCryptoEncodeContext;
263b34ccadSLei He 
273b34ccadSLei He /* rsaEncryption: 1.2.840.113549.1.1.1 */
283b34ccadSLei He #define QCRYPTO_OID_rsaEncryption "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01"
293b34ccadSLei He 
3099d423f1SLei He /* Simple decoder used to parse DER encoded rsa keys. */
3199d423f1SLei He 
3299d423f1SLei He /**
3399d423f1SLei He  *  @opaque: user context.
3499d423f1SLei He  *  @value: the starting address of |value| part of 'Tag-Length-Value' pattern.
3599d423f1SLei He  *  @vlen: length of the |value|.
3699d423f1SLei He  *  Returns: 0 for success, any other value is considered an error.
3799d423f1SLei He  */
3899d423f1SLei He typedef int (*QCryptoDERDecodeCb) (void *opaque, const uint8_t *value,
3999d423f1SLei He                                    size_t vlen, Error **errp);
4099d423f1SLei He 
4199d423f1SLei He /**
4299d423f1SLei He  * qcrypto_der_decode_int:
4399d423f1SLei He  * @data: pointer to address of input data
4499d423f1SLei He  * @dlen: pointer to length of input data
4599d423f1SLei He  * @cb: callback invoked when decode succeed, if cb equals NULL, no
4699d423f1SLei He  * callback will be invoked
4799d423f1SLei He  * @opaque: parameter passed to cb
4899d423f1SLei He  *
4999d423f1SLei He  * Decode integer from DER-encoded data.
5099d423f1SLei He  *
5199d423f1SLei He  * Returns: On success, *data points to rest data, and *dlen
5299d423f1SLei He  * will be set to the rest length of data, if cb is not NULL, must
5399d423f1SLei He  * return 0 to make decode success, at last, the length of the data
5499d423f1SLei He  * part of the decoded INTEGER will be returned. Otherwise, -1 is
553b34ccadSLei He  * returned and the valued of *data and *dlen keep unchanged.
5699d423f1SLei He  */
5799d423f1SLei He int qcrypto_der_decode_int(const uint8_t **data,
5899d423f1SLei He                            size_t *dlen,
5999d423f1SLei He                            QCryptoDERDecodeCb cb,
6099d423f1SLei He                            void *opaque,
6199d423f1SLei He                            Error **errp);
6299d423f1SLei He /**
6399d423f1SLei He  * qcrypto_der_decode_seq:
6499d423f1SLei He  *
6599d423f1SLei He  * Decode sequence from DER-encoded data, similar with der_decode_int.
6699d423f1SLei He  *
6799d423f1SLei He  * @data: pointer to address of input data
6899d423f1SLei He  * @dlen: pointer to length of input data
6999d423f1SLei He  * @cb: callback invoked when decode succeed, if cb equals NULL, no
7099d423f1SLei He  * callback will be invoked
7199d423f1SLei He  * @opaque: parameter passed to cb
7299d423f1SLei He  *
7399d423f1SLei He  * Returns: On success, *data points to rest data, and *dlen
7499d423f1SLei He  * will be set to the rest length of data, if cb is not NULL, must
7599d423f1SLei He  * return 0 to make decode success, at last, the length of the data
7699d423f1SLei He  * part of the decoded SEQUENCE will be returned. Otherwise, -1 is
773b34ccadSLei He  * returned and the valued of *data and *dlen keep unchanged.
7899d423f1SLei He  */
7999d423f1SLei He int qcrypto_der_decode_seq(const uint8_t **data,
8099d423f1SLei He                            size_t *dlen,
8199d423f1SLei He                            QCryptoDERDecodeCb cb,
8299d423f1SLei He                            void *opaque,
8399d423f1SLei He                            Error **errp);
8499d423f1SLei He 
853b34ccadSLei He /**
863b34ccadSLei He  * qcrypto_der_decode_oid:
873b34ccadSLei He  *
883b34ccadSLei He  * Decode OID from DER-encoded data, similar with der_decode_int.
893b34ccadSLei He  *
903b34ccadSLei He  * @data: pointer to address of input data
913b34ccadSLei He  * @dlen: pointer to length of input data
923b34ccadSLei He  * @cb: callback invoked when decode succeed, if cb equals NULL, no
933b34ccadSLei He  * callback will be invoked
943b34ccadSLei He  * @opaque: parameter passed to cb
953b34ccadSLei He  *
963b34ccadSLei He  * Returns: On success, *data points to rest data, and *dlen
973b34ccadSLei He  * will be set to the rest length of data, if cb is not NULL, must
983b34ccadSLei He  * return 0 to make decode success, at last, the length of the data
993b34ccadSLei He  * part of the decoded OID will be returned. Otherwise, -1 is
1003b34ccadSLei He  * returned and the valued of *data and *dlen keep unchanged.
1013b34ccadSLei He  */
1023b34ccadSLei He int qcrypto_der_decode_oid(const uint8_t **data,
1033b34ccadSLei He                            size_t *dlen,
1043b34ccadSLei He                            QCryptoDERDecodeCb cb,
1053b34ccadSLei He                            void *opaque,
1063b34ccadSLei He                            Error **errp);
1073b34ccadSLei He 
1083b34ccadSLei He /**
1093b34ccadSLei He  * qcrypto_der_decode_octet_str:
1103b34ccadSLei He  *
1113b34ccadSLei He  * Decode OCTET STRING from DER-encoded data, similar with der_decode_int.
1123b34ccadSLei He  *
1133b34ccadSLei He  * @data: pointer to address of input data
1143b34ccadSLei He  * @dlen: pointer to length of input data
1153b34ccadSLei He  * @cb: callback invoked when decode succeed, if cb equals NULL, no
1163b34ccadSLei He  * callback will be invoked
1173b34ccadSLei He  * @opaque: parameter passed to cb
1183b34ccadSLei He  *
1193b34ccadSLei He  * Returns: On success, *data points to rest data, and *dlen
1203b34ccadSLei He  * will be set to the rest length of data, if cb is not NULL, must
1213b34ccadSLei He  * return 0 to make decode success, at last, the length of the data
1223b34ccadSLei He  * part of the decoded OCTET STRING will be returned. Otherwise, -1 is
1233b34ccadSLei He  * returned and the valued of *data and *dlen keep unchanged.
1243b34ccadSLei He  */
1253b34ccadSLei He int qcrypto_der_decode_octet_str(const uint8_t **data,
1263b34ccadSLei He                                  size_t *dlen,
1273b34ccadSLei He                                  QCryptoDERDecodeCb cb,
1283b34ccadSLei He                                  void *opaque,
1293b34ccadSLei He                                  Error **errp);
1303b34ccadSLei He 
1313b34ccadSLei He /**
1323b34ccadSLei He  * qcrypto_der_decode_bit_str:
1333b34ccadSLei He  *
1343b34ccadSLei He  * Decode BIT STRING from DER-encoded data, similar with der_decode_int.
1353b34ccadSLei He  *
1363b34ccadSLei He  * @data: pointer to address of input data
1373b34ccadSLei He  * @dlen: pointer to length of input data
1383b34ccadSLei He  * @cb: callback invoked when decode succeed, if cb equals NULL, no
1393b34ccadSLei He  * callback will be invoked
1403b34ccadSLei He  * @opaque: parameter passed to cb
1413b34ccadSLei He  *
1423b34ccadSLei He  * Returns: On success, *data points to rest data, and *dlen
1433b34ccadSLei He  * will be set to the rest length of data, if cb is not NULL, must
1443b34ccadSLei He  * return 0 to make decode success, at last, the length of the data
1453b34ccadSLei He  * part of the decoded BIT STRING will be returned. Otherwise, -1 is
1463b34ccadSLei He  * returned and the valued of *data and *dlen keep unchanged.
1473b34ccadSLei He  */
1483b34ccadSLei He int qcrypto_der_decode_bit_str(const uint8_t **data,
1493b34ccadSLei He                                size_t *dlen,
1503b34ccadSLei He                                QCryptoDERDecodeCb cb,
1513b34ccadSLei He                                void *opaque,
1523b34ccadSLei He                                Error **errp);
1533b34ccadSLei He 
1543b34ccadSLei He 
1553b34ccadSLei He /**
1563b34ccadSLei He  * qcrypto_der_decode_ctx_tag:
1573b34ccadSLei He  *
1583b34ccadSLei He  * Decode context specific tag
1593b34ccadSLei He  *
1603b34ccadSLei He  * @data: pointer to address of input data
1613b34ccadSLei He  * @dlen: pointer to length of input data
1623b34ccadSLei He  * @tag: expected value of context specific tag
1633b34ccadSLei He  * @cb: callback invoked when decode succeed, if cb equals NULL, no
1643b34ccadSLei He  * callback will be invoked
1653b34ccadSLei He  * @opaque: parameter passed to cb
1663b34ccadSLei He  *
1673b34ccadSLei He  * Returns: On success, *data points to rest data, and *dlen
1683b34ccadSLei He  * will be set to the rest length of data, if cb is not NULL, must
1693b34ccadSLei He  * return 0 to make decode success, at last, the length of the data
1703b34ccadSLei He  * part of the decoded BIT STRING will be returned. Otherwise, -1 is
1713b34ccadSLei He  * returned and the valued of *data and *dlen keep unchanged.
1723b34ccadSLei He  */
1733b34ccadSLei He int qcrypto_der_decode_ctx_tag(const uint8_t **data,
1743b34ccadSLei He                                size_t *dlen, int tag_id,
1753b34ccadSLei He                                QCryptoDERDecodeCb cb,
1763b34ccadSLei He                                void *opaque,
1773b34ccadSLei He                                Error **errp);
1783b34ccadSLei He 
1793b34ccadSLei He /**
1803b34ccadSLei He  * qcrypto_der_encode_ctx_new:
1813b34ccadSLei He  *
1823b34ccadSLei He  * Allocate a context used for der encoding.
1833b34ccadSLei He  */
1843b34ccadSLei He QCryptoEncodeContext *qcrypto_der_encode_ctx_new(void);
1853b34ccadSLei He 
1863b34ccadSLei He /**
1873b34ccadSLei He  * qcrypto_der_encode_seq_begin:
1883b34ccadSLei He  * @ctx: the encode context.
1893b34ccadSLei He  *
1903b34ccadSLei He  * Start encoding a SEQUENCE for ctx.
1913b34ccadSLei He  *
1923b34ccadSLei He  */
1933b34ccadSLei He void qcrypto_der_encode_seq_begin(QCryptoEncodeContext *ctx);
1943b34ccadSLei He 
1953b34ccadSLei He /**
1963b34ccadSLei He  * qcrypto_der_encode_seq_begin:
1973b34ccadSLei He  * @ctx: the encode context.
1983b34ccadSLei He  *
1993b34ccadSLei He  * Finish uencoding a SEQUENCE for ctx.
2003b34ccadSLei He  *
2013b34ccadSLei He  */
2023b34ccadSLei He void qcrypto_der_encode_seq_end(QCryptoEncodeContext *ctx);
2033b34ccadSLei He 
2043b34ccadSLei He 
2053b34ccadSLei He /**
2063b34ccadSLei He  * qcrypto_der_encode_oid:
2073b34ccadSLei He  * @ctx: the encode context.
2083b34ccadSLei He  * @src: the source data of oid, note it should be already encoded, this
2093b34ccadSLei He  * function only add tag and length part for it.
2103b34ccadSLei He  *
2113b34ccadSLei He  * Encode an oid into ctx.
2123b34ccadSLei He  */
2133b34ccadSLei He void qcrypto_der_encode_oid(QCryptoEncodeContext *ctx,
2143b34ccadSLei He                             const uint8_t *src, size_t src_len);
2153b34ccadSLei He 
2163b34ccadSLei He /**
2173b34ccadSLei He  * qcrypto_der_encode_int:
2183b34ccadSLei He  * @ctx: the encode context.
2193b34ccadSLei He  * @src: the source data of integer, note it should be already encoded, this
2203b34ccadSLei He  * function only add tag and length part for it.
2213b34ccadSLei He  *
2223b34ccadSLei He  * Encode an integer into ctx.
2233b34ccadSLei He  */
2243b34ccadSLei He void qcrypto_der_encode_int(QCryptoEncodeContext *ctx,
2253b34ccadSLei He                             const uint8_t *src, size_t src_len);
2263b34ccadSLei He 
2273b34ccadSLei He /**
2283b34ccadSLei He  * qcrypto_der_encode_null:
2293b34ccadSLei He  * @ctx: the encode context.
2303b34ccadSLei He  *
2313b34ccadSLei He  * Encode a null into ctx.
2323b34ccadSLei He  */
2333b34ccadSLei He void qcrypto_der_encode_null(QCryptoEncodeContext *ctx);
2343b34ccadSLei He 
2353b34ccadSLei He /**
2363b34ccadSLei He  * qcrypto_der_encode_octet_str:
2373b34ccadSLei He  * @ctx: the encode context.
2383b34ccadSLei He  * @src: the source data of the octet string.
2393b34ccadSLei He  *
2403b34ccadSLei He  * Encode a octet string into ctx.
2413b34ccadSLei He  */
2423b34ccadSLei He void qcrypto_der_encode_octet_str(QCryptoEncodeContext *ctx,
2433b34ccadSLei He                                   const uint8_t *src, size_t src_len);
2443b34ccadSLei He 
2453b34ccadSLei He /**
2463b34ccadSLei He  * qcrypto_der_encode_octet_str_begin:
2473b34ccadSLei He  * @ctx: the encode context.
2483b34ccadSLei He  *
2493b34ccadSLei He  * Start encoding a octet string, All fields between
2503b34ccadSLei He  * qcrypto_der_encode_octet_str_begin and qcrypto_der_encode_octet_str_end
2513b34ccadSLei He  * are encoded as an octet string. This is useful when we need to encode a
252*0a19d879SMichael Tokarev  * encoded SEQUENCE as OCTET STRING.
2533b34ccadSLei He  */
2543b34ccadSLei He void qcrypto_der_encode_octet_str_begin(QCryptoEncodeContext *ctx);
2553b34ccadSLei He 
2563b34ccadSLei He /**
2573b34ccadSLei He  * qcrypto_der_encode_octet_str_end:
2583b34ccadSLei He  * @ctx: the encode context.
2593b34ccadSLei He  *
2603b34ccadSLei He  * Finish encoding a octet string, All fields between
2613b34ccadSLei He  * qcrypto_der_encode_octet_str_begin and qcrypto_der_encode_octet_str_end
2623b34ccadSLei He  * are encoded as an octet string. This is useful when we need to encode a
263*0a19d879SMichael Tokarev  * encoded SEQUENCE as OCTET STRING.
2643b34ccadSLei He  */
2653b34ccadSLei He void qcrypto_der_encode_octet_str_end(QCryptoEncodeContext *ctx);
2663b34ccadSLei He 
2673b34ccadSLei He /**
2683b34ccadSLei He  * qcrypto_der_encode_ctx_buffer_len:
2693b34ccadSLei He  * @ctx: the encode context.
2703b34ccadSLei He  *
2713b34ccadSLei He  * Compute the expected buffer size to save all encoded things.
2723b34ccadSLei He  */
2733b34ccadSLei He size_t qcrypto_der_encode_ctx_buffer_len(QCryptoEncodeContext *ctx);
2743b34ccadSLei He 
2753b34ccadSLei He /**
2763b34ccadSLei He  * qcrypto_der_encode_ctx_flush_and_free:
2773b34ccadSLei He  * @ctx: the encode context.
278*0a19d879SMichael Tokarev  * @dst: the destination to save the encoded data, the length of dst should
2793b34ccadSLei He  * not less than qcrypto_der_encode_cxt_buffer_len
2803b34ccadSLei He  *
2813b34ccadSLei He  * Flush all encoded data into dst, then free ctx.
2823b34ccadSLei He  */
2833b34ccadSLei He void qcrypto_der_encode_ctx_flush_and_free(QCryptoEncodeContext *ctx,
2843b34ccadSLei He                                            uint8_t *dst);
2853b34ccadSLei He 
28699d423f1SLei He #endif  /* QCRYPTO_ASN1_DECODER_H */
287