xref: /xnu-10002.81.5/EXTERNAL_HEADERS/corecrypto/ccder.h (revision 5e3eaea39dcf651e66cb99ba7d70e32cc4a99587)
1 /* Copyright (c) (2012,2013,2014,2015,2016,2017,2018,2019,2021) 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_PURE
92 size_t ccder_sizeof_implicit_integer(ccder_tag implicit_tag, cc_size n, const cc_unit *s);
93 
94 CC_PURE
95 size_t ccder_sizeof_implicit_octet_string(ccder_tag implicit_tag, cc_size n, const cc_unit *s);
96 
97 CC_CONST
98 size_t ccder_sizeof_implicit_raw_octet_string(ccder_tag implicit_tag, size_t s_size);
99 
100 CC_CONST
101 size_t ccder_sizeof_implicit_uint64(ccder_tag implicit_tag, uint64_t value);
102 
103 CC_PURE
104 size_t ccder_sizeof_integer(cc_size n, const cc_unit *s);
105 
106 CC_CONST
107 size_t ccder_sizeof_len(size_t len);
108 
109 CC_PURE
110 size_t ccder_sizeof_octet_string(cc_size n, const cc_unit *s);
111 
112 CC_PURE
113 size_t ccder_sizeof_oid(ccoid_t oid);
114 
115 CC_CONST
116 size_t ccder_sizeof_raw_octet_string(size_t s_size);
117 
118 CC_CONST
119 size_t ccder_sizeof_tag(ccder_tag tag);
120 
121 CC_CONST
122 size_t ccder_sizeof_uint64(uint64_t value);
123 
124 CC_PURE
125 size_t ccder_sizeof_eckey(size_t priv_size, ccoid_t oid, size_t pub_size);
126 
127 /* alias of ccder_sizeof_eckey */
128 CC_PURE
129 size_t ccder_encode_eckey_size(size_t priv_size, ccoid_t oid, size_t pub_size);
130 
131 /* All of the original functions are unavailable in a ptrcheck build. */
132 // MARK: - Encode/decode functions, unavailable in ptrcheck
133 
134 /* Encode a tag backwards, der_end should point to one byte past the end of
135    destination for the tag, returns a pointer to the first byte of the tag.
136    Returns NULL if there is an encoding error. */
137 CC_NONNULL((2)) cc_ptrcheck_unavailable()
138 uint8_t *ccder_encode_tag(ccder_tag tag, const uint8_t *der, uint8_t *der_end);
139 
140 /* Returns a pointer to the start of the len field.  returns NULL if there
141  is an encoding error. */
142 CC_NONNULL((2)) cc_ptrcheck_unavailable()
143 uint8_t *ccder_encode_len(size_t len, const uint8_t *der, uint8_t *der_end);
144 
145 /* der_end should point to the first byte of the content of this der item. */
146 CC_NONNULL((3)) cc_ptrcheck_unavailable()
147 uint8_t *ccder_encode_tl(ccder_tag tag, size_t len, const uint8_t *der, uint8_t *der_end);
148 
149 CC_PURE CC_NONNULL((2)) cc_ptrcheck_unavailable()
150 uint8_t *ccder_encode_body_nocopy(size_t size, const uint8_t *der, uint8_t *der_end);
151 
152 /* Encode the tag and length of a constructed object.  der is the lower
153    bound, der_end is one byte paste where we want to write the length and
154    body_end is one byte past the end of the body of the der object we are
155    encoding the tag and length of. */
156 CC_NONNULL((2, 3)) cc_ptrcheck_unavailable()
157 uint8_t *ccder_encode_constructed_tl(ccder_tag tag, const uint8_t *body_end, const uint8_t *der, uint8_t *der_end);
158 
159 /* Encodes oid into der and returns der + ccder_sizeof_oid(oid). */
160 CC_NONNULL((1, 2)) cc_ptrcheck_unavailable()
161 uint8_t *ccder_encode_oid(ccoid_t oid, const uint8_t *der, uint8_t *der_end);
162 
163 CC_NONNULL((3, 4)) cc_ptrcheck_unavailable()
164 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);
165 
166 CC_NONNULL((2, 3)) cc_ptrcheck_unavailable()
167 uint8_t *ccder_encode_integer(cc_size n, const cc_unit *s, const uint8_t *der, uint8_t *der_end);
168 
169 CC_NONNULL((3)) cc_ptrcheck_unavailable()
170 uint8_t *ccder_encode_implicit_uint64(ccder_tag implicit_tag, uint64_t value, const uint8_t *der, uint8_t *der_end);
171 
172 CC_NONNULL((2)) cc_ptrcheck_unavailable()
173 uint8_t *ccder_encode_uint64(uint64_t value, const uint8_t *der, uint8_t *der_end);
174 
175 CC_NONNULL((3, 4)) cc_ptrcheck_unavailable()
176 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);
177 
178 CC_NONNULL((2, 3)) cc_ptrcheck_unavailable()
179 uint8_t *ccder_encode_octet_string(cc_size n, const cc_unit *s, const uint8_t *der, uint8_t *der_end);
180 
181 CC_NONNULL((3, 4)) cc_ptrcheck_unavailable()
182 uint8_t *ccder_encode_implicit_raw_octet_string(ccder_tag implicit_tag,
183                                                 size_t s_size,
184                                                 const uint8_t *s,
185                                                 const uint8_t *der,
186                                                 uint8_t *der_end);
187 
188 CC_NONNULL((2, 3)) cc_ptrcheck_unavailable()
189 uint8_t *ccder_encode_raw_octet_string(size_t s_size, const uint8_t *s, const uint8_t *der, uint8_t *der_end);
190 
191 CC_NONNULL((2, 5, 6)) cc_ptrcheck_unavailable()
192 uint8_t *ccder_encode_eckey(size_t priv_size,
193                             const uint8_t *priv_key,
194                             ccoid_t oid,
195                             size_t pub_size,
196                             const uint8_t *pub_key,
197                             uint8_t *der,
198                             uint8_t *der_end);
199 
200 /* ccder_encode_body COPIES the body into the der.
201    It's inefficient – especially when you already have to convert to get to
202    the form for the body.
203    see encode integer for the right way to unify conversion and insertion */
204 CC_NONNULL((3)) cc_ptrcheck_unavailable()
205 uint8_t *ccder_encode_body(size_t size, const uint8_t *body, const uint8_t *der, uint8_t *der_end);
206 
207 /* Returns a pointer to the start of the length field, and returns the decoded tag in tag.
208  returns NULL if there is a decoding error. */
209 CC_NONNULL((1, 3)) cc_ptrcheck_unavailable()
210 const uint8_t *ccder_decode_tag(ccder_tag *tagp, const uint8_t *der, const uint8_t *der_end);
211 
212 CC_NONNULL((1, 3)) cc_ptrcheck_unavailable()
213 const uint8_t *ccder_decode_len(size_t *lenp, const uint8_t *der, const uint8_t *der_end);
214 
215 /*!
216  @function   ccder_decode_len_strict
217  @abstract   Decode the length of a DER encoded item
218 
219  @param      lenp     Pointer to the length of the DER item
220  @param      der      Beginning of input DER buffer
221  @param      der_end  End of input DER buffer
222 
223  @result     First byte after the parsed length or NULL if the length is not valid (i.e. when the length isn't DER encoded)
224  */
225 CC_NONNULL((1, 3)) cc_ptrcheck_unavailable()
226 const uint8_t *ccder_decode_len_strict(size_t *lenp, const uint8_t *der, const uint8_t *der_end);
227 
228 /* Returns a pointer to the start of the der object, and returns the length in len.
229  returns NULL if there is a decoding error. */
230 CC_NONNULL((2, 4)) cc_ptrcheck_unavailable()
231 const uint8_t *ccder_decode_tl(ccder_tag expected_tag, size_t *lenp, const uint8_t *der, const uint8_t *der_end);
232 
233 /*!
234  @function   ccder_decode_tl_strict
235  @abstract   Decode a tag and length from a DER object given an expected tag.
236 
237  @param      expected_tag  Tag of expected DER object pointed to by `der`
238  @param      lenp          Output length of DER object
239  @param      der           Beginning of input DER buffer
240  @param      der_end       End of input DER buffer
241 
242  @result     Pointer to the DER object with the length contained in `lenp` otherwise NULL.
243  */
244 CC_NONNULL((2, 4)) cc_ptrcheck_unavailable()
245 const uint8_t *ccder_decode_tl_strict(ccder_tag expected_tag, size_t *lenp, const uint8_t *der, const uint8_t *der_end);
246 
247 CC_NONNULL((2, 4)) cc_ptrcheck_unavailable()
248 const uint8_t *ccder_decode_constructed_tl(ccder_tag expected_tag,
249                                            const uint8_t **body_end,
250                                            const uint8_t *der,
251                                            const uint8_t *der_end);
252 
253 /*!
254  @function   ccder_decode_constructed_tl_strict
255  @abstract   Decode a tag and length from a contstructed DER object given an expected tag.
256 
257  @param      expected_tag  Tag of expected DER object pointed to by `der`
258  @param      body_end      Pointer to hold the end of the sequence
259  @param      der           Beginning of input DER buffer
260  @param      der_end       End of input DER buffer
261 
262  @result     Pointer to the first DER object within the constructed object and the length of the total constructed object
263  contained in `lenp`; NULL otherwise.
264  */
265 CC_NONNULL((2, 4)) cc_ptrcheck_unavailable()
266 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);
267 
268 CC_NONNULL((1, 3)) cc_ptrcheck_unavailable()
269 const uint8_t *ccder_decode_sequence_tl(const uint8_t **body_end, const uint8_t *der, const uint8_t *der_end);
270 
271 /*!
272  @function   ccder_decode_sequence_tl_strict
273  @abstract   Decode a DER sequence.
274 
275  @param      body_end Pointer to hold the end of the sequence
276  @param      der      Beginning of input DER buffer
277  @param      der_end  End of input DER buffer
278 
279  @result     Pointer to the first DER object within the sequence otherwise NULL.
280  */
281 CC_NONNULL((1, 3)) cc_ptrcheck_unavailable()
282 const uint8_t *ccder_decode_sequence_tl_strict(const uint8_t **body_end, const uint8_t *der, const uint8_t *der_end);
283 
284 /*!
285  @function   ccder_decode_uint_n
286  @abstract   length in cc_unit of a der unsigned integer after skipping the leading zeroes
287 
288  @param      der           Beginning of input DER buffer
289  @param      der_end  End of input DER buffer
290  @param      n               Output the number of cc_unit required to represent the number
291 
292  @result     First byte after the parsed integer or
293         NULL if the integer is not valid (negative) or reach der_end when reading the integer
294  */
295 CC_NONNULL((3)) cc_ptrcheck_unavailable()
296 const uint8_t *ccder_decode_uint_n(cc_size *n, const uint8_t *der, const uint8_t *der_end);
297 
298 /*!
299  @function   ccder_decode_uint
300  @abstract   Represent in cc_unit a ber unsigned integer after skipping the leading zeroes
301 
302  @param      der           Beginning of input BER buffer
303  @param      der_end  End of input BER buffer
304  @param      n                Number of cc_unit allocated for r
305  @param      r                Allocated array of cc_unit to copy the integer into.
306 
307  @result     First byte after the parsed integer or
308 NULL if the integer is not valid (negative)
309             reach der_end when reading the integer
310             n cc_unit is not enough to represent the integer
311  */
312 CC_NONNULL((4)) cc_ptrcheck_unavailable()
313 const uint8_t *ccder_decode_uint(cc_size n, cc_unit *r, const uint8_t *der, const uint8_t *der_end);
314 
315 /*!
316  @function   ccder_decode_uint_strict
317  @abstract   Represent in cc_unit a der unsigned integer after skipping the leading zeroes
318 
319  @param      n        Number of cc_unit allocated for r
320  @param      r        Allocated array of cc_unit to copy the integer into.
321  @param      der      Beginning of input DER buffer
322  @param      der_end  End of input DER buffer
323 
324  @result     First byte after the parsed integer or NULL if the integer is not valid.
325  */
326 CC_NONNULL((4)) cc_ptrcheck_unavailable()
327 const uint8_t *ccder_decode_uint_strict(cc_size n, cc_unit *r, const uint8_t *der, const uint8_t *der_end);
328 
329 CC_NONNULL((3)) cc_ptrcheck_unavailable()
330 const uint8_t *ccder_decode_uint64(uint64_t *r, const uint8_t *der, const uint8_t *der_end);
331 
332 /* Decode SEQUENCE { r, s -- (unsigned)integer } in ber into r and s.
333    Returns NULL on decode errors, returns pointer just past the end of the
334    sequence of integers otherwise. */
335 CC_NONNULL((2, 3, 5)) cc_ptrcheck_unavailable()
336 const uint8_t *ccder_decode_seqii(cc_size n, cc_unit *r, cc_unit *s, const uint8_t *der, const uint8_t *der_end);
337 
338 /*!
339  @function   ccder_decode_seqii_strict
340  @abstract   Parse a DER sequence of two integers.
341 
342  @param      n        The maximum unit size of the integers.
343  @param      r        First integer output
344  @param      s        Second integer output
345  @param      der      Beginning of input DER buffer
346  @param      der_end  End of input DER buffer
347 
348  @result     Null on error, otherwise a pointer just past the end of the sequence buffer
349  */
350 CC_NONNULL((2, 3, 5)) cc_ptrcheck_unavailable()
351 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);
352 
353 /*!
354  @function   ccder_decode_oid
355  @abstract   Parse a DER sequence representing an oid.
356 
357  @param      oidp     Pointer to OID
358  @param      der      Beginning of input DER buffer
359  @param      der_end  End of input DER buffer
360 
361  @result     Null on error, otherwise a pointer just past the end of the sequence buffer.
362 
363  @warning    In case of error, *oidp is set to NULL.
364              Otherwise, *oidp is a pointer to a buffer of "unsigned char" of size >= 2.
365  */
366 CC_NONNULL((1, 3)) cc_ptrcheck_unavailable()
367 const uint8_t *ccder_decode_oid(ccoid_t *oidp, const uint8_t *der, const uint8_t *der_end);
368 
369 CC_NONNULL((1, 2, 4)) cc_ptrcheck_unavailable()
370 const uint8_t *ccder_decode_bitstring(const uint8_t **bit_string, size_t *bit_length, const uint8_t *der, const uint8_t *der_end);
371 
372 CC_NONNULL((1, 2, 3, 4, 5, 6, 7)) cc_ptrcheck_unavailable()
373 const uint8_t *ccder_decode_eckey(uint64_t *version,
374                                   size_t *priv_size,
375                                   const uint8_t **priv_key,
376                                   ccoid_t *oid,
377                                   size_t *pub_size,
378                                   const uint8_t **pub_key,
379                                   const uint8_t *der,
380                                   const uint8_t *der_end);
381 
382 // MARK: -
383 
384 #define CC_EC_OID_SECP192R1                                           \
385     {                                                                 \
386         ((unsigned char *)"\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x01") \
387     }
388 #define CC_EC_OID_SECP256R1                                           \
389     {                                                                 \
390         ((unsigned char *)"\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07") \
391     }
392 #define CC_EC_OID_SECP224R1                               \
393     {                                                     \
394         ((unsigned char *)"\x06\x05\x2B\x81\x04\x00\x21") \
395     }
396 #define CC_EC_OID_SECP384R1                               \
397     {                                                     \
398         ((unsigned char *)"\x06\x05\x2B\x81\x04\x00\x22") \
399     }
400 #define CC_EC_OID_SECP521R1                               \
401     {                                                     \
402         ((unsigned char *)"\x06\x05\x2B\x81\x04\x00\x23") \
403     }
404 
405 #endif /* _CORECRYPTO_CCDER_H_ */
406