xref: /xnu-11215.41.3/EXTERNAL_HEADERS/corecrypto/ccder.h (revision 33de042d024d46de5ff4e89f2471de6608e37fa4)
1 /* Copyright (c) (2012-2019,2021,2022) Apple Inc. All rights reserved.
2  *
3  * corecrypto is licensed under Apple Inc.’s Internal Use License Agreement (which
4  * is contained in the License.txt file distributed with corecrypto) and only to
5  * people who accept that license. IMPORTANT:  Any license rights granted to you by
6  * Apple Inc. (if any) are limited to internal use within your organization only on
7  * devices and computers you own or control, for the sole purpose of verifying the
8  * security characteristics and correct functioning of the Apple Software.  You may
9  * not, directly or indirectly, redistribute the Apple Software or any portions thereof.
10  */
11 
12 #ifndef _CORECRYPTO_CCDER_H_
13 #define _CORECRYPTO_CCDER_H_
14 
15 #include <corecrypto/cc.h>
16 #include <corecrypto/ccasn1.h>
17 #include <corecrypto/ccn.h>
18 #include <corecrypto/ccder_blob.h>
19 
20 /* DER types to be used with ccder_decode and ccder_encode functions. */
21 #define CCDER_EOL CCASN1_EOL
22 #define CCDER_BOOLEAN CCASN1_BOOLEAN
23 #define CCDER_INTEGER CCASN1_INTEGER
24 #define CCDER_BIT_STRING CCASN1_BIT_STRING
25 #define CCDER_OCTET_STRING CCASN1_OCTET_STRING
26 #define CCDER_NULL CCASN1_NULL
27 #define CCDER_OBJECT_IDENTIFIER CCASN1_OBJECT_IDENTIFIER
28 #define CCDER_OBJECT_DESCRIPTOR CCASN1_OBJECT_DESCRIPTOR
29 /* External or instance-of 0x08 */
30 #define CCDER_REAL CCASN1_REAL
31 #define CCDER_ENUMERATED CCASN1_ENUMERATED
32 #define CCDER_EMBEDDED_PDV CCASN1_EMBEDDED_PDV
33 #define CCDER_UTF8_STRING CCASN1_UTF8_STRING
34 /*                         0x0d */
35 /*                         0x0e */
36 /*                         0x0f */
37 #define CCDER_SEQUENCE CCASN1_SEQUENCE
38 #define CCDER_SET CCASN1_SET
39 #define CCDER_NUMERIC_STRING CCASN1_NUMERIC_STRING
40 #define CCDER_PRINTABLE_STRING CCASN1_PRINTABLE_STRING
41 #define CCDER_T61_STRING CCASN1_T61_STRING
42 #define CCDER_VIDEOTEX_STRING CCASN1_VIDEOTEX_STRING
43 #define CCDER_IA5_STRING CCASN1_IA5_STRING
44 #define CCDER_UTC_TIME CCASN1_UTC_TIME
45 #define CCDER_GENERALIZED_TIME CCASN1_GENERALIZED_TIME
46 #define CCDER_GRAPHIC_STRING CCASN1_GRAPHIC_STRING
47 #define CCDER_VISIBLE_STRING CCASN1_VISIBLE_STRING
48 #define CCDER_GENERAL_STRING CCASN1_GENERAL_STRING
49 #define CCDER_UNIVERSAL_STRING CCASN1_UNIVERSAL_STRING
50 /*                         0x1d */
51 #define CCDER_BMP_STRING CCASN1_BMP_STRING
52 #define CCDER_HIGH_TAG_NUMBER CCASN1_HIGH_TAG_NUMBER
53 #define CCDER_TELETEX_STRING CCDER_T61_STRING
54 
55 #ifdef CCDER_MULTIBYTE_TAGS
56 #define CCDER_TAG_MASK ((ccder_tag)~0)
57 #define CCDER_TAGNUM_MASK ((ccder_tag) ~((ccder_tag)7 << (sizeof(ccder_tag) * 8 - 3)))
58 
59 #define CCDER_METHOD_MASK ((ccder_tag)1 << (sizeof(ccder_tag) * 8 - 3))
60 #define CCDER_PRIMITIVE ((ccder_tag)0 << (sizeof(ccder_tag) * 8 - 3))
61 #define CCDER_CONSTRUCTED ((ccder_tag)1 << (sizeof(ccder_tag) * 8 - 3))
62 
63 #define CCDER_CLASS_MASK ((ccder_tag)3 << (sizeof(ccder_tag) * 8 - 2))
64 #define CCDER_UNIVERSAL ((ccder_tag)0 << (sizeof(ccder_tag) * 8 - 2))
65 #define CCDER_APPLICATION ((ccder_tag)1 << (sizeof(ccder_tag) * 8 - 2))
66 #define CCDER_CONTEXT_SPECIFIC ((ccder_tag)2 << (sizeof(ccder_tag) * 8 - 2))
67 #define CCDER_PRIVATE ((ccder_tag)3 << (sizeof(ccder_tag) * 8 - 2))
68 #else /* !CCDER_MULTIBYTE_TAGS */
69 #define CCDER_TAG_MASK CCASN1_TAG_MASK
70 #define CCDER_TAGNUM_MASK CCASN1_TAGNUM_MASK
71 
72 #define CCDER_METHOD_MASK CCASN1_METHOD_MASK
73 #define CCDER_PRIMITIVE CCASN1_PRIMITIVE
74 #define CCDER_CONSTRUCTED CCASN1_CONSTRUCTED
75 
76 #define CCDER_CLASS_MASK CCASN1_CLASS_MASK
77 #define CCDER_UNIVERSAL CCASN1_UNIVERSAL
78 #define CCDER_APPLICATION CCASN1_APPLICATION
79 #define CCDER_CONTEXT_SPECIFIC CCASN1_CONTEXT_SPECIFIC
80 #define CCDER_PRIVATE CCASN1_PRIVATE
81 #endif /* !CCDER_MULTIBYTE_TAGS */
82 #define CCDER_CONSTRUCTED_SET (CCDER_SET | CCDER_CONSTRUCTED)
83 #define CCDER_CONSTRUCTED_SEQUENCE (CCDER_SEQUENCE | CCDER_CONSTRUCTED)
84 
85 // MARK: - ccder_sizeof_ functions
86 
87 /* Returns the size of an asn1 encoded item of length l in bytes. */
88 CC_CONST
89 size_t ccder_sizeof(ccder_tag tag, size_t len);
90 
91 CC_NONNULL_ALL
92 size_t ccder_sizeof_overflow(ccder_tag tag, size_t nbytes, bool *overflowed);
93 
94 CC_PURE
95 size_t ccder_sizeof_implicit_integer(ccder_tag implicit_tag, cc_size n, const cc_unit *s);
96 
97 CC_PURE
98 size_t ccder_sizeof_implicit_octet_string(ccder_tag implicit_tag, cc_size n, const cc_unit *s);
99 
100 CC_CONST
101 size_t ccder_sizeof_implicit_raw_octet_string(ccder_tag implicit_tag, size_t s_size);
102 
103 CC_NONNULL_ALL
104 size_t ccder_sizeof_implicit_raw_octet_string_overflow(ccder_tag implicit_tag, size_t s_size, bool *overflowed);
105 
106 CC_CONST
107 size_t ccder_sizeof_implicit_uint64(ccder_tag implicit_tag, uint64_t value);
108 
109 CC_PURE
110 size_t ccder_sizeof_integer(cc_size n, const cc_unit *s);
111 
112 CC_CONST
113 size_t ccder_sizeof_len(size_t len);
114 
115 CC_PURE
116 size_t ccder_sizeof_octet_string(cc_size n, const cc_unit *s);
117 
118 CC_PURE
119 size_t ccder_sizeof_oid(ccoid_t oid);
120 
121 CC_CONST
122 size_t ccder_sizeof_raw_octet_string(size_t s_size);
123 
124 CC_CONST
125 size_t ccder_sizeof_tag(ccder_tag tag);
126 
127 CC_CONST
128 size_t ccder_sizeof_uint64(uint64_t value);
129 
130 CC_PURE
131 size_t ccder_sizeof_eckey(size_t priv_size, ccoid_t oid, size_t pub_size);
132 
133 /* alias of ccder_sizeof_eckey */
134 CC_PURE
135 size_t ccder_encode_eckey_size(size_t priv_size, ccoid_t oid, size_t pub_size);
136 
137 /* All of the original functions are unavailable in a ptrcheck build. */
138 // MARK: - Encode/decode functions, unavailable in ptrcheck
139 
140 /* Encode a tag backwards, der_end should point to one byte past the end of
141    destination for the tag, returns a pointer to the first byte of the tag.
142    Returns NULL if there is an encoding error. */
143 CC_NONNULL((2)) cc_ptrcheck_unavailable()
144 uint8_t *ccder_encode_tag(ccder_tag tag, const uint8_t *der, uint8_t *der_end);
145 
146 /* Returns a pointer to the start of the len field.  returns NULL if there
147  is an encoding error. */
148 CC_NONNULL((2)) cc_ptrcheck_unavailable()
149 uint8_t *ccder_encode_len(size_t len, const uint8_t *der, uint8_t *der_end);
150 
151 /* der_end should point to the first byte of the content of this der item. */
152 CC_NONNULL((3)) cc_ptrcheck_unavailable()
153 uint8_t *ccder_encode_tl(ccder_tag tag, size_t len, const uint8_t *der, uint8_t *der_end);
154 
155 CC_PURE CC_NONNULL((2)) cc_ptrcheck_unavailable()
156 uint8_t *ccder_encode_body_nocopy(size_t size, const uint8_t *der, uint8_t *der_end);
157 
158 /* Encode the tag and length of a constructed object.  der is the lower
159    bound, der_end is one byte paste where we want to write the length and
160    body_end is one byte past the end of the body of the der object we are
161    encoding the tag and length of. */
162 CC_NONNULL((2, 3)) cc_ptrcheck_unavailable()
163 uint8_t *ccder_encode_constructed_tl(ccder_tag tag, const uint8_t *body_end, const uint8_t *der, uint8_t *der_end);
164 
165 /* Encodes oid into der and returns der + ccder_sizeof_oid(oid). */
166 CC_NONNULL((1, 2)) cc_ptrcheck_unavailable()
167 uint8_t *ccder_encode_oid(ccoid_t oid, const uint8_t *der, uint8_t *der_end);
168 
169 CC_NONNULL((3, 4)) cc_ptrcheck_unavailable()
170 uint8_t *ccder_encode_implicit_integer(ccder_tag implicit_tag, cc_size n, const cc_unit *s, const uint8_t *der, uint8_t *der_end);
171 
172 CC_NONNULL((2, 3)) cc_ptrcheck_unavailable()
173 uint8_t *ccder_encode_integer(cc_size n, const cc_unit *s, const uint8_t *der, uint8_t *der_end);
174 
175 CC_NONNULL((3)) cc_ptrcheck_unavailable()
176 uint8_t *ccder_encode_implicit_uint64(ccder_tag implicit_tag, uint64_t value, const uint8_t *der, uint8_t *der_end);
177 
178 CC_NONNULL((2)) cc_ptrcheck_unavailable()
179 uint8_t *ccder_encode_uint64(uint64_t value, const uint8_t *der, uint8_t *der_end);
180 
181 CC_NONNULL((3, 4)) cc_ptrcheck_unavailable()
182 uint8_t *ccder_encode_implicit_octet_string(ccder_tag implicit_tag, cc_size n, const cc_unit *s, const uint8_t *der, uint8_t *der_end);
183 
184 CC_NONNULL((2, 3)) cc_ptrcheck_unavailable()
185 uint8_t *ccder_encode_octet_string(cc_size n, const cc_unit *s, const uint8_t *der, uint8_t *der_end);
186 
187 CC_NONNULL((3, 4)) cc_ptrcheck_unavailable()
188 uint8_t *ccder_encode_implicit_raw_octet_string(ccder_tag implicit_tag,
189                                                 size_t s_size,
190                                                 const uint8_t *s,
191                                                 const uint8_t *der,
192                                                 uint8_t *der_end);
193 
194 CC_NONNULL((2, 3)) cc_ptrcheck_unavailable()
195 uint8_t *ccder_encode_raw_octet_string(size_t s_size, const uint8_t *s, const uint8_t *der, uint8_t *der_end);
196 
197 CC_NONNULL((2, 5, 6)) cc_ptrcheck_unavailable()
198 uint8_t *ccder_encode_eckey(size_t priv_size,
199                             const uint8_t *priv_key,
200                             ccoid_t oid,
201                             size_t pub_size,
202                             const uint8_t *pub_key,
203                             uint8_t *der,
204                             uint8_t *der_end);
205 
206 /* ccder_encode_body COPIES the body into the der.
207    It's inefficient – especially when you already have to convert to get to
208    the form for the body.
209    see encode integer for the right way to unify conversion and insertion */
210 CC_NONNULL((3)) cc_ptrcheck_unavailable()
211 uint8_t *ccder_encode_body(size_t size, const uint8_t *body, const uint8_t *der, uint8_t *der_end);
212 
213 /* Returns a pointer to the start of the length field, and returns the decoded tag in tag.
214  returns NULL if there is a decoding error. */
215 CC_NONNULL((1, 3)) cc_ptrcheck_unavailable()
216 const uint8_t *ccder_decode_tag(ccder_tag *tagp, const uint8_t *der, const uint8_t *der_end);
217 
218 CC_NONNULL((1, 3)) cc_ptrcheck_unavailable()
219 const uint8_t *ccder_decode_len(size_t *lenp, const uint8_t *der, const uint8_t *der_end);
220 
221 /*!
222  @function   ccder_decode_len_strict
223  @abstract   Decode the length of a DER encoded item
224 
225  @param      lenp     Pointer to the length of the DER item
226  @param      der      Beginning of input DER buffer
227  @param      der_end  End of input DER buffer
228 
229  @result     First byte after the parsed length or NULL if the length is not valid (i.e. when the length isn't DER encoded)
230  */
231 CC_NONNULL((1, 3)) cc_ptrcheck_unavailable()
232 const uint8_t *ccder_decode_len_strict(size_t *lenp, const uint8_t *der, const uint8_t *der_end);
233 
234 /* Returns a pointer to the start of the der object, and returns the length in len.
235  returns NULL if there is a decoding error. */
236 CC_NONNULL((2, 4)) cc_ptrcheck_unavailable()
237 const uint8_t *ccder_decode_tl(ccder_tag expected_tag, size_t *lenp, const uint8_t *der, const uint8_t *der_end);
238 
239 /*!
240  @function   ccder_decode_tl_strict
241  @abstract   Decode a tag and length from a DER object given an expected tag.
242 
243  @param      expected_tag  Tag of expected DER object pointed to by `der`
244  @param      lenp          Output length of DER object
245  @param      der           Beginning of input DER buffer
246  @param      der_end       End of input DER buffer
247 
248  @result     Pointer to the DER object with the length contained in `lenp` otherwise NULL.
249  */
250 CC_NONNULL((2, 4)) cc_ptrcheck_unavailable()
251 const uint8_t *ccder_decode_tl_strict(ccder_tag expected_tag, size_t *lenp, const uint8_t *der, const uint8_t *der_end);
252 
253 CC_NONNULL((2, 4)) cc_ptrcheck_unavailable()
254 const uint8_t *ccder_decode_constructed_tl(ccder_tag expected_tag,
255                                            const uint8_t **body_end,
256                                            const uint8_t *der,
257                                            const uint8_t *der_end);
258 
259 /*!
260  @function   ccder_decode_constructed_tl_strict
261  @abstract   Decode a tag and length from a contstructed DER object given an expected tag.
262 
263  @param      expected_tag  Tag of expected DER object pointed to by `der`
264  @param      body_end      Pointer to hold the end of the sequence
265  @param      der           Beginning of input DER buffer
266  @param      der_end       End of input DER buffer
267 
268  @result     Pointer to the first DER object within the constructed object and the length of the total constructed object
269  contained in `lenp`; NULL otherwise.
270  */
271 CC_NONNULL((2, 4)) cc_ptrcheck_unavailable()
272 const uint8_t *ccder_decode_constructed_tl_strict(ccder_tag expected_tag, const uint8_t **body_end, const uint8_t *der, const uint8_t *der_end);
273 
274 CC_NONNULL((1, 3)) cc_ptrcheck_unavailable()
275 const uint8_t *ccder_decode_sequence_tl(const uint8_t **body_end, const uint8_t *der, const uint8_t *der_end);
276 
277 /*!
278  @function   ccder_decode_sequence_tl_strict
279  @abstract   Decode a DER sequence.
280 
281  @param      body_end Pointer to hold the end of the sequence
282  @param      der      Beginning of input DER buffer
283  @param      der_end  End of input DER buffer
284 
285  @result     Pointer to the first DER object within the sequence otherwise NULL.
286  */
287 CC_NONNULL((1, 3)) cc_ptrcheck_unavailable()
288 const uint8_t *ccder_decode_sequence_tl_strict(const uint8_t **body_end, const uint8_t *der, const uint8_t *der_end);
289 
290 /*!
291  @function   ccder_decode_uint_n
292  @abstract   length in cc_unit of a der unsigned integer after skipping the leading zeroes
293 
294  @param      der           Beginning of input DER buffer
295  @param      der_end  End of input DER buffer
296  @param      n               Output the number of cc_unit required to represent the number
297 
298  @result     First byte after the parsed integer or
299         NULL if the integer is not valid (negative) or reach der_end when reading the integer
300  */
301 CC_NONNULL((3)) cc_ptrcheck_unavailable()
302 const uint8_t *ccder_decode_uint_n(cc_size *n, const uint8_t *der, const uint8_t *der_end);
303 
304 /*!
305  @function   ccder_decode_uint
306  @abstract   Represent in cc_unit a ber unsigned integer after skipping the leading zeroes
307 
308  @param      der           Beginning of input BER buffer
309  @param      der_end  End of input BER buffer
310  @param      n                Number of cc_unit allocated for r
311  @param      r                Allocated array of cc_unit to copy the integer into.
312 
313  @result     First byte after the parsed integer or
314 NULL if the integer is not valid (negative)
315             reach der_end when reading the integer
316             n cc_unit is not enough to represent the integer
317  */
318 CC_NONNULL((4)) cc_ptrcheck_unavailable()
319 const uint8_t *ccder_decode_uint(cc_size n, cc_unit *r, const uint8_t *der, const uint8_t *der_end);
320 
321 /*!
322  @function   ccder_decode_uint_strict
323  @abstract   Represent in cc_unit a der unsigned integer after skipping the leading zeroes
324 
325  @param      n        Number of cc_unit allocated for r
326  @param      r        Allocated array of cc_unit to copy the integer into.
327  @param      der      Beginning of input DER buffer
328  @param      der_end  End of input DER buffer
329 
330  @result     First byte after the parsed integer or NULL if the integer is not valid.
331  */
332 CC_NONNULL((4)) cc_ptrcheck_unavailable()
333 const uint8_t *ccder_decode_uint_strict(cc_size n, cc_unit *r, const uint8_t *der, const uint8_t *der_end);
334 
335 CC_NONNULL((3)) cc_ptrcheck_unavailable()
336 const uint8_t *ccder_decode_uint64(uint64_t *r, const uint8_t *der, const uint8_t *der_end);
337 
338 /* Decode SEQUENCE { r, s -- (unsigned)integer } in ber into r and s.
339    Returns NULL on decode errors, returns pointer just past the end of the
340    sequence of integers otherwise. */
341 CC_NONNULL((2, 3, 5)) cc_ptrcheck_unavailable()
342 const uint8_t *ccder_decode_seqii(cc_size n, cc_unit *r, cc_unit *s, const uint8_t *der, const uint8_t *der_end);
343 
344 /*!
345  @function   ccder_decode_seqii_strict
346  @abstract   Parse a DER sequence of two integers.
347 
348  @param      n        The maximum unit size of the integers.
349  @param      r        First integer output
350  @param      s        Second integer output
351  @param      der      Beginning of input DER buffer
352  @param      der_end  End of input DER buffer
353 
354  @result     Null on error, otherwise a pointer just past the end of the sequence buffer
355  */
356 CC_NONNULL((2, 3, 5)) cc_ptrcheck_unavailable()
357 const uint8_t *ccder_decode_seqii_strict(cc_size n, cc_unit *r, cc_unit *s, const uint8_t *der, const uint8_t *der_end);
358 
359 /*!
360  @function   ccder_decode_oid
361  @abstract   Parse a DER sequence representing an oid.
362 
363  @param      oidp     Pointer to OID
364  @param      der      Beginning of input DER buffer
365  @param      der_end  End of input DER buffer
366 
367  @result     Null on error, otherwise a pointer just past the end of the sequence buffer.
368 
369  @warning    In case of error, *oidp is set to NULL.
370              Otherwise, *oidp is a pointer to a buffer of "unsigned char" of size >= 2.
371  */
372 CC_NONNULL((1, 3)) cc_ptrcheck_unavailable()
373 const uint8_t *ccder_decode_oid(ccoid_t *oidp, const uint8_t *der, const uint8_t *der_end);
374 
375 CC_NONNULL((1, 2, 4)) cc_ptrcheck_unavailable()
376 const uint8_t *ccder_decode_bitstring(const uint8_t **bit_string, size_t *bit_length, const uint8_t *der, const uint8_t *der_end);
377 
378 CC_NONNULL((1, 2, 3, 4, 5, 6, 7)) cc_ptrcheck_unavailable()
379 const uint8_t *ccder_decode_eckey(uint64_t *version,
380                                   size_t *priv_size,
381                                   const uint8_t **priv_key,
382                                   ccoid_t *oid,
383                                   size_t *pub_size,
384                                   const uint8_t **pub_key,
385                                   const uint8_t *der,
386                                   const uint8_t *der_end);
387 
388 // MARK: -
389 
390 #define CC_EC_OID_SECP192R1                                           \
391     {                                                                 \
392         ((unsigned char *)"\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x01") \
393     }
394 #define CC_EC_OID_SECP256R1                                           \
395     {                                                                 \
396         ((unsigned char *)"\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07") \
397     }
398 #define CC_EC_OID_SECP224R1                               \
399     {                                                     \
400         ((unsigned char *)"\x06\x05\x2B\x81\x04\x00\x21") \
401     }
402 #define CC_EC_OID_SECP384R1                               \
403     {                                                     \
404         ((unsigned char *)"\x06\x05\x2B\x81\x04\x00\x22") \
405     }
406 #define CC_EC_OID_SECP521R1                               \
407     {                                                     \
408         ((unsigned char *)"\x06\x05\x2B\x81\x04\x00\x23") \
409     }
410 
411 #endif /* _CORECRYPTO_CCDER_H_ */
412