xref: /openbmc/qemu/crypto/der.h (revision 047f2ca1cec9cdb226f4eac7e672f753089a42ee)
1  /*
2   * Copyright (c) 2022 Bytedance
3   * Author: lei he <helei.sig11@bytedance.com>
4   *
5   * This library is free software; you can redistribute it and/or
6   * modify it under the terms of the GNU Lesser General Public
7   * License as published by the Free Software Foundation; either
8   * version 2.1 of the License, or (at your option) any later version.
9   *
10   * This library is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   * Lesser General Public License for more details.
14   *
15   * You should have received a copy of the GNU Lesser General Public
16   * License along with this library; if not, see <http://www.gnu.org/licenses/>.
17   *
18   */
19  
20  #ifndef QCRYPTO_ASN1_DECODER_H
21  #define QCRYPTO_ASN1_DECODER_H
22  
23  #include "qapi/error.h"
24  
25  typedef struct QCryptoEncodeContext QCryptoEncodeContext;
26  
27  /* rsaEncryption: 1.2.840.113549.1.1.1 */
28  #define QCRYPTO_OID_rsaEncryption "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01"
29  
30  /* Simple decoder used to parse DER encoded rsa keys. */
31  
32  /**
33   *  @opaque: user context.
34   *  @value: the starting address of |value| part of 'Tag-Length-Value' pattern.
35   *  @vlen: length of the |value|.
36   *  Returns: 0 for success, any other value is considered an error.
37   */
38  typedef int (*QCryptoDERDecodeCb) (void *opaque, const uint8_t *value,
39                                     size_t vlen, Error **errp);
40  
41  /**
42   * qcrypto_der_decode_int:
43   * @data: pointer to address of input data
44   * @dlen: pointer to length of input data
45   * @cb: callback invoked when decode succeed, if cb equals NULL, no
46   * callback will be invoked
47   * @opaque: parameter passed to cb
48   *
49   * Decode integer from DER-encoded data.
50   *
51   * Returns: On success, *data points to rest data, and *dlen
52   * will be set to the rest length of data, if cb is not NULL, must
53   * return 0 to make decode success, at last, the length of the data
54   * part of the decoded INTEGER will be returned. Otherwise, -1 is
55   * returned and the valued of *data and *dlen keep unchanged.
56   */
57  int qcrypto_der_decode_int(const uint8_t **data,
58                             size_t *dlen,
59                             QCryptoDERDecodeCb cb,
60                             void *opaque,
61                             Error **errp);
62  /**
63   * qcrypto_der_decode_seq:
64   *
65   * Decode sequence from DER-encoded data, similar with der_decode_int.
66   *
67   * @data: pointer to address of input data
68   * @dlen: pointer to length of input data
69   * @cb: callback invoked when decode succeed, if cb equals NULL, no
70   * callback will be invoked
71   * @opaque: parameter passed to cb
72   *
73   * Returns: On success, *data points to rest data, and *dlen
74   * will be set to the rest length of data, if cb is not NULL, must
75   * return 0 to make decode success, at last, the length of the data
76   * part of the decoded SEQUENCE will be returned. Otherwise, -1 is
77   * returned and the valued of *data and *dlen keep unchanged.
78   */
79  int qcrypto_der_decode_seq(const uint8_t **data,
80                             size_t *dlen,
81                             QCryptoDERDecodeCb cb,
82                             void *opaque,
83                             Error **errp);
84  
85  /**
86   * qcrypto_der_decode_oid:
87   *
88   * Decode OID from DER-encoded data, similar with der_decode_int.
89   *
90   * @data: pointer to address of input data
91   * @dlen: pointer to length of input data
92   * @cb: callback invoked when decode succeed, if cb equals NULL, no
93   * callback will be invoked
94   * @opaque: parameter passed to cb
95   *
96   * Returns: On success, *data points to rest data, and *dlen
97   * will be set to the rest length of data, if cb is not NULL, must
98   * return 0 to make decode success, at last, the length of the data
99   * part of the decoded OID will be returned. Otherwise, -1 is
100   * returned and the valued of *data and *dlen keep unchanged.
101   */
102  int qcrypto_der_decode_oid(const uint8_t **data,
103                             size_t *dlen,
104                             QCryptoDERDecodeCb cb,
105                             void *opaque,
106                             Error **errp);
107  
108  /**
109   * qcrypto_der_decode_octet_str:
110   *
111   * Decode OCTET STRING from DER-encoded data, similar with der_decode_int.
112   *
113   * @data: pointer to address of input data
114   * @dlen: pointer to length of input data
115   * @cb: callback invoked when decode succeed, if cb equals NULL, no
116   * callback will be invoked
117   * @opaque: parameter passed to cb
118   *
119   * Returns: On success, *data points to rest data, and *dlen
120   * will be set to the rest length of data, if cb is not NULL, must
121   * return 0 to make decode success, at last, the length of the data
122   * part of the decoded OCTET STRING will be returned. Otherwise, -1 is
123   * returned and the valued of *data and *dlen keep unchanged.
124   */
125  int qcrypto_der_decode_octet_str(const uint8_t **data,
126                                   size_t *dlen,
127                                   QCryptoDERDecodeCb cb,
128                                   void *opaque,
129                                   Error **errp);
130  
131  /**
132   * qcrypto_der_decode_bit_str:
133   *
134   * Decode BIT STRING from DER-encoded data, similar with der_decode_int.
135   *
136   * @data: pointer to address of input data
137   * @dlen: pointer to length of input data
138   * @cb: callback invoked when decode succeed, if cb equals NULL, no
139   * callback will be invoked
140   * @opaque: parameter passed to cb
141   *
142   * Returns: On success, *data points to rest data, and *dlen
143   * will be set to the rest length of data, if cb is not NULL, must
144   * return 0 to make decode success, at last, the length of the data
145   * part of the decoded BIT STRING will be returned. Otherwise, -1 is
146   * returned and the valued of *data and *dlen keep unchanged.
147   */
148  int qcrypto_der_decode_bit_str(const uint8_t **data,
149                                 size_t *dlen,
150                                 QCryptoDERDecodeCb cb,
151                                 void *opaque,
152                                 Error **errp);
153  
154  
155  /**
156   * qcrypto_der_decode_ctx_tag:
157   *
158   * Decode context specific tag
159   *
160   * @data: pointer to address of input data
161   * @dlen: pointer to length of input data
162   * @tag: expected value of context specific tag
163   * @cb: callback invoked when decode succeed, if cb equals NULL, no
164   * callback will be invoked
165   * @opaque: parameter passed to cb
166   *
167   * Returns: On success, *data points to rest data, and *dlen
168   * will be set to the rest length of data, if cb is not NULL, must
169   * return 0 to make decode success, at last, the length of the data
170   * part of the decoded BIT STRING will be returned. Otherwise, -1 is
171   * returned and the valued of *data and *dlen keep unchanged.
172   */
173  int qcrypto_der_decode_ctx_tag(const uint8_t **data,
174                                 size_t *dlen, int tag_id,
175                                 QCryptoDERDecodeCb cb,
176                                 void *opaque,
177                                 Error **errp);
178  
179  /**
180   * qcrypto_der_encode_ctx_new:
181   *
182   * Allocate a context used for der encoding.
183   */
184  QCryptoEncodeContext *qcrypto_der_encode_ctx_new(void);
185  
186  /**
187   * qcrypto_der_encode_seq_begin:
188   * @ctx: the encode context.
189   *
190   * Start encoding a SEQUENCE for ctx.
191   *
192   */
193  void qcrypto_der_encode_seq_begin(QCryptoEncodeContext *ctx);
194  
195  /**
196   * qcrypto_der_encode_seq_begin:
197   * @ctx: the encode context.
198   *
199   * Finish uencoding a SEQUENCE for ctx.
200   *
201   */
202  void qcrypto_der_encode_seq_end(QCryptoEncodeContext *ctx);
203  
204  
205  /**
206   * qcrypto_der_encode_oid:
207   * @ctx: the encode context.
208   * @src: the source data of oid, note it should be already encoded, this
209   * function only add tag and length part for it.
210   *
211   * Encode an oid into ctx.
212   */
213  void qcrypto_der_encode_oid(QCryptoEncodeContext *ctx,
214                              const uint8_t *src, size_t src_len);
215  
216  /**
217   * qcrypto_der_encode_int:
218   * @ctx: the encode context.
219   * @src: the source data of integer, note it should be already encoded, this
220   * function only add tag and length part for it.
221   *
222   * Encode an integer into ctx.
223   */
224  void qcrypto_der_encode_int(QCryptoEncodeContext *ctx,
225                              const uint8_t *src, size_t src_len);
226  
227  /**
228   * qcrypto_der_encode_null:
229   * @ctx: the encode context.
230   *
231   * Encode a null into ctx.
232   */
233  void qcrypto_der_encode_null(QCryptoEncodeContext *ctx);
234  
235  /**
236   * qcrypto_der_encode_octet_str:
237   * @ctx: the encode context.
238   * @src: the source data of the octet string.
239   *
240   * Encode a octet string into ctx.
241   */
242  void qcrypto_der_encode_octet_str(QCryptoEncodeContext *ctx,
243                                    const uint8_t *src, size_t src_len);
244  
245  /**
246   * qcrypto_der_encode_octet_str_begin:
247   * @ctx: the encode context.
248   *
249   * Start encoding a octet string, All fields between
250   * qcrypto_der_encode_octet_str_begin and qcrypto_der_encode_octet_str_end
251   * are encoded as an octet string. This is useful when we need to encode a
252   * encoded SEQUNCE as OCTET STRING.
253   */
254  void qcrypto_der_encode_octet_str_begin(QCryptoEncodeContext *ctx);
255  
256  /**
257   * qcrypto_der_encode_octet_str_end:
258   * @ctx: the encode context.
259   *
260   * Finish encoding a octet string, All fields between
261   * qcrypto_der_encode_octet_str_begin and qcrypto_der_encode_octet_str_end
262   * are encoded as an octet string. This is useful when we need to encode a
263   * encoded SEQUNCE as OCTET STRING.
264   */
265  void qcrypto_der_encode_octet_str_end(QCryptoEncodeContext *ctx);
266  
267  /**
268   * qcrypto_der_encode_ctx_buffer_len:
269   * @ctx: the encode context.
270   *
271   * Compute the expected buffer size to save all encoded things.
272   */
273  size_t qcrypto_der_encode_ctx_buffer_len(QCryptoEncodeContext *ctx);
274  
275  /**
276   * qcrypto_der_encode_ctx_flush_and_free:
277   * @ctx: the encode context.
278   * @dst: the distination to save the encoded data, the length of dst should
279   * not less than qcrypto_der_encode_cxt_buffer_len
280   *
281   * Flush all encoded data into dst, then free ctx.
282   */
283  void qcrypto_der_encode_ctx_flush_and_free(QCryptoEncodeContext *ctx,
284                                             uint8_t *dst);
285  
286  #endif  /* QCRYPTO_ASN1_DECODER_H */
287