xref: /xnu-8020.101.4/EXTERNAL_HEADERS/corecrypto/ccder.h (revision e7776783b89a353188416a9a346c6cdb4928faad)
1 /* Copyright (c) (2012,2013,2014,2015,2016,2017,2018,2019) 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/ccasn1.h>
16 #include <corecrypto/ccn.h>
17 
18 #define CCDER_MULTIBYTE_TAGS 1
19 
20 #ifdef CCDER_MULTIBYTE_TAGS
21 typedef unsigned long ccder_tag;
22 #else
23 typedef uint8_t ccder_tag;
24 #endif
25 
26 /* DER types to be used with ccder_decode and ccder_encode functions. */
27 #define CCDER_EOL CCASN1_EOL
28 #define CCDER_BOOLEAN CCASN1_BOOLEAN
29 #define CCDER_INTEGER CCASN1_INTEGER
30 #define CCDER_BIT_STRING CCASN1_BIT_STRING
31 #define CCDER_OCTET_STRING CCASN1_OCTET_STRING
32 #define CCDER_NULL CCASN1_NULL
33 #define CCDER_OBJECT_IDENTIFIER CCASN1_OBJECT_IDENTIFIER
34 #define CCDER_OBJECT_DESCRIPTOR CCASN1_OBJECT_DESCRIPTOR
35 /* External or instance-of 0x08 */
36 #define CCDER_REAL CCASN1_REAL
37 #define CCDER_ENUMERATED CCASN1_ENUMERATED
38 #define CCDER_EMBEDDED_PDV CCASN1_EMBEDDED_PDV
39 #define CCDER_UTF8_STRING CCASN1_UTF8_STRING
40 /*                         0x0d */
41 /*                         0x0e */
42 /*                         0x0f */
43 #define CCDER_SEQUENCE CCASN1_SEQUENCE
44 #define CCDER_SET CCASN1_SET
45 #define CCDER_NUMERIC_STRING CCASN1_NUMERIC_STRING
46 #define CCDER_PRINTABLE_STRING CCASN1_PRINTABLE_STRING
47 #define CCDER_T61_STRING CCASN1_T61_STRING
48 #define CCDER_VIDEOTEX_STRING CCASN1_VIDEOTEX_STRING
49 #define CCDER_IA5_STRING CCASN1_IA5_STRING
50 #define CCDER_UTC_TIME CCASN1_UTC_TIME
51 #define CCDER_GENERALIZED_TIME CCASN1_GENERALIZED_TIME
52 #define CCDER_GRAPHIC_STRING CCASN1_GRAPHIC_STRING
53 #define CCDER_VISIBLE_STRING CCASN1_VISIBLE_STRING
54 #define CCDER_GENERAL_STRING CCASN1_GENERAL_STRING
55 #define CCDER_UNIVERSAL_STRING CCASN1_UNIVERSAL_STRING
56 /*                         0x1d */
57 #define CCDER_BMP_STRING CCASN1_BMP_STRING
58 #define CCDER_HIGH_TAG_NUMBER CCASN1_HIGH_TAG_NUMBER
59 #define CCDER_TELETEX_STRING CCDER_T61_STRING
60 
61 #ifdef CCDER_MULTIBYTE_TAGS
62 #define CCDER_TAG_MASK ((ccder_tag)~0)
63 #define CCDER_TAGNUM_MASK ((ccder_tag) ~((ccder_tag)7 << (sizeof(ccder_tag) * 8 - 3)))
64 
65 #define CCDER_METHOD_MASK ((ccder_tag)1 << (sizeof(ccder_tag) * 8 - 3))
66 #define CCDER_PRIMITIVE ((ccder_tag)0 << (sizeof(ccder_tag) * 8 - 3))
67 #define CCDER_CONSTRUCTED ((ccder_tag)1 << (sizeof(ccder_tag) * 8 - 3))
68 
69 #define CCDER_CLASS_MASK ((ccder_tag)3 << (sizeof(ccder_tag) * 8 - 2))
70 #define CCDER_UNIVERSAL ((ccder_tag)0 << (sizeof(ccder_tag) * 8 - 2))
71 #define CCDER_APPLICATION ((ccder_tag)1 << (sizeof(ccder_tag) * 8 - 2))
72 #define CCDER_CONTEXT_SPECIFIC ((ccder_tag)2 << (sizeof(ccder_tag) * 8 - 2))
73 #define CCDER_PRIVATE ((ccder_tag)3 << (sizeof(ccder_tag) * 8 - 2))
74 #else /* !CCDER_MULTIBYTE_TAGS */
75 #define CCDER_TAG_MASK CCASN1_TAG_MASK
76 #define CCDER_TAGNUM_MASK CCASN1_TAGNUM_MASK
77 
78 #define CCDER_METHOD_MASK CCASN1_METHOD_MASK
79 #define CCDER_PRIMITIVE CCASN1_PRIMITIVE
80 #define CCDER_CONSTRUCTED CCASN1_CONSTRUCTED
81 
82 #define CCDER_CLASS_MASK CCASN1_CLASS_MASK
83 #define CCDER_UNIVERSAL CCASN1_UNIVERSAL
84 #define CCDER_APPLICATION CCASN1_APPLICATION
85 #define CCDER_CONTEXT_SPECIFIC CCASN1_CONTEXT_SPECIFIC
86 #define CCDER_PRIVATE CCASN1_PRIVATE
87 #endif /* !CCDER_MULTIBYTE_TAGS */
88 #define CCDER_CONSTRUCTED_SET (CCDER_SET | CCDER_CONSTRUCTED)
89 #define CCDER_CONSTRUCTED_SEQUENCE (CCDER_SEQUENCE | CCDER_CONSTRUCTED)
90 
91 // MARK: ccder_sizeof_ functions
92 
93 /* Returns the size of an asn1 encoded item of length l in bytes. */
94 CC_CONST
95 size_t ccder_sizeof(ccder_tag tag, size_t len);
96 
97 CC_PURE
98 size_t ccder_sizeof_implicit_integer(ccder_tag implicit_tag, cc_size n, const cc_unit *s);
99 
100 CC_PURE
101 size_t ccder_sizeof_implicit_octet_string(ccder_tag implicit_tag, cc_size n, const cc_unit *s);
102 
103 CC_CONST
104 size_t ccder_sizeof_implicit_raw_octet_string(ccder_tag implicit_tag, size_t s_size);
105 CC_CONST
106 size_t ccder_sizeof_implicit_uint64(ccder_tag implicit_tag, uint64_t value);
107 
108 CC_PURE
109 size_t ccder_sizeof_integer(cc_size n, const cc_unit *s);
110 
111 CC_CONST
112 size_t ccder_sizeof_len(size_t len);
113 
114 CC_PURE
115 size_t ccder_sizeof_octet_string(cc_size n, const cc_unit *s);
116 
117 CC_PURE
118 size_t ccder_sizeof_oid(ccoid_t oid);
119 
120 CC_CONST
121 size_t ccder_sizeof_raw_octet_string(size_t s_size);
122 
123 CC_CONST
124 size_t ccder_sizeof_tag(ccder_tag tag);
125 
126 CC_CONST
127 size_t ccder_sizeof_uint64(uint64_t value);
128 
129 // MARK: ccder_encode_ functions.
130 
131 /* Encode a tag backwards, der_end should point to one byte past the end of
132    destination for the tag, returns a pointer to the first byte of the tag.
133    Returns NULL if there is an encoding error. */
134 CC_NONNULL((2))
135 uint8_t *ccder_encode_tag(ccder_tag tag, const uint8_t *der, uint8_t *der_end);
136 
137 /* Returns a pointer to the start of the len field.  returns NULL if there
138  is an encoding error. */
139 CC_NONNULL((2))
140 uint8_t *ccder_encode_len(size_t len, const uint8_t *der, uint8_t *der_end);
141 
142 /* der_end should point to the first byte of the content of this der item. */
143 CC_NONNULL((3))
144 uint8_t *ccder_encode_tl(ccder_tag tag, size_t len, const uint8_t *der, uint8_t *der_end);
145 
146 CC_PURE CC_NONNULL((2)) uint8_t *ccder_encode_body_nocopy(size_t size, const uint8_t *der, uint8_t *der_end);
147 
148 /* Encode the tag and length of a constructed object.  der is the lower
149    bound, der_end is one byte paste where we want to write the length and
150    body_end is one byte past the end of the body of the der object we are
151    encoding the tag and length of. */
152 CC_NONNULL((2, 3))
153 uint8_t *ccder_encode_constructed_tl(ccder_tag tag, const uint8_t *body_end, const uint8_t *der, uint8_t *der_end);
154 
155 /* Encodes oid into der and returns
156  der + ccder_sizeof_oid(oid). */
157 CC_NONNULL((1, 2))
158 uint8_t *ccder_encode_oid(ccoid_t oid, const uint8_t *der, uint8_t *der_end);
159 
160 CC_NONNULL((3, 4))
161 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);
162 
163 CC_NONNULL((2, 3))
164 uint8_t *ccder_encode_integer(cc_size n, const cc_unit *s, const uint8_t *der, uint8_t *der_end);
165 
166 CC_NONNULL((3))
167 uint8_t *ccder_encode_implicit_uint64(ccder_tag implicit_tag, uint64_t value, const uint8_t *der, uint8_t *der_end);
168 
169 CC_NONNULL((2))
170 uint8_t *ccder_encode_uint64(uint64_t value, const uint8_t *der, uint8_t *der_end);
171 
172 CC_NONNULL((3, 4))
173 uint8_t *
174 ccder_encode_implicit_octet_string(ccder_tag implicit_tag, cc_size n, const cc_unit *s, const uint8_t *der, uint8_t *der_end);
175 
176 CC_NONNULL((2, 3))
177 uint8_t *ccder_encode_octet_string(cc_size n, const cc_unit *s, const uint8_t *der, uint8_t *der_end);
178 
179 CC_NONNULL((3, 4))
180 uint8_t *ccder_encode_implicit_raw_octet_string(ccder_tag implicit_tag,
181                                                 size_t s_size,
182                                                 const uint8_t *s,
183                                                 const uint8_t *der,
184                                                 uint8_t *der_end);
185 
186 CC_NONNULL((2, 3))
187 uint8_t *ccder_encode_raw_octet_string(size_t s_size, const uint8_t *s, const uint8_t *der, uint8_t *der_end);
188 
189 size_t ccder_encode_eckey_size(size_t priv_size, ccoid_t oid, size_t pub_size);
190 
191 CC_NONNULL((2, 5, 6, 7))
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))
205 uint8_t *ccder_encode_body(size_t size, const uint8_t *body, const uint8_t *der, uint8_t *der_end);
206 
207 // MARK: ccder_decode_ functions.
208 
209 /* Returns a pointer to the start of the length field, and returns the decoded tag in tag.
210  returns NULL if there is a decoding error. */
211 CC_NONNULL((1, 3))
212 const uint8_t *ccder_decode_tag(ccder_tag *tagp, const uint8_t *der, const uint8_t *der_end);
213 
214 CC_NONNULL((1, 3))
215 const uint8_t *ccder_decode_len(size_t *lenp, const uint8_t *der, const uint8_t *der_end);
216 
217 /*!
218  @function   ccder_decode_len_strict
219  @abstract   Decode the length of a DER encoded item
220 
221  @param      lenp     Pointer to the length of the DER item
222  @param      der      Beginning of input DER buffer
223  @param      der_end  End of input DER buffer
224 
225  @result     First byte after the parsed length or NULL if the length is not valid (i.e. when the length isn't DER encoded)
226  */
227 CC_NONNULL((1, 3))
228 const uint8_t *ccder_decode_len_strict(size_t *lenp, const uint8_t *der, const uint8_t *der_end);
229 
230 /* Returns a pointer to the start of the der object, and returns the length in len.
231  returns NULL if there is a decoding error. */
232 CC_NONNULL((2, 4))
233 const uint8_t *ccder_decode_tl(ccder_tag expected_tag, size_t *lenp, const uint8_t *der, const uint8_t *der_end);
234 
235 /*!
236  @function   ccder_decode_tl_strict
237  @abstract   Decode a tag and length from a DER object given an expected tag.
238 
239  @param      expected_tag  Tag of expected DER object pointed to by `der`
240  @param      lenp          Output length of DER object
241  @param      der           Beginning of input DER buffer
242  @param      der_end       End of input DER buffer
243 
244  @result     Pointer to the DER object with the length contained in `lenp` otherwise NULL.
245  */
246 CC_NONNULL((2, 4))
247 const uint8_t *ccder_decode_tl_strict(ccder_tag expected_tag, size_t *lenp, const uint8_t *der, const uint8_t *der_end);
248 
249 CC_NONNULL((2, 4))
250 const uint8_t *
251 ccder_decode_constructed_tl(ccder_tag expected_tag, const uint8_t **body_end, const uint8_t *der, 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))
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))
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))
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 
296 CC_NONNULL((3))
297 const uint8_t *ccder_decode_uint_n(cc_size *n, const uint8_t *der, const uint8_t *der_end);
298 
299 /*!
300  @function   ccder_decode_uint
301  @abstract   Represent in cc_unit a ber unsigned integer after skipping the leading zeroes
302 
303  @param      der           Beginning of input BER buffer
304  @param      der_end  End of input BER buffer
305  @param      n                Number of cc_unit allocated for r
306  @param      r                Allocated array of cc_unit to copy the integer into.
307 
308  @result     First byte after the parsed integer or
309 NULL if the integer is not valid (negative)
310             reach der_end when reading the integer
311             n cc_unit is not enough to represent the integer
312  */
313 CC_NONNULL((4))
314 const uint8_t *ccder_decode_uint(cc_size n, cc_unit *r, const uint8_t *der, const uint8_t *der_end);
315 
316 /*!
317  @function   ccder_decode_uint_strict
318  @abstract   Represent in cc_unit a der unsigned integer after skipping the leading zeroes
319 
320  @param      n        Number of cc_unit allocated for r
321  @param      r        Allocated array of cc_unit to copy the integer into.
322  @param      der      Beginning of input DER buffer
323  @param      der_end  End of input DER buffer
324 
325  @result     First byte after the parsed integer or NULL if the integer is not valid.
326  */
327 CC_NONNULL((4))
328 const uint8_t *ccder_decode_uint_strict(cc_size n, cc_unit *r, const uint8_t *der, const uint8_t *der_end);
329 
330 CC_NONNULL((3))
331 const uint8_t *ccder_decode_uint64(uint64_t *r, const uint8_t *der, const uint8_t *der_end);
332 
333 /* Decode SEQUENCE { r, s -- (unsigned)integer } in ber into r and s.
334    Returns NULL on decode errors, returns pointer just past the end of the
335    sequence of integers otherwise. */
336 CC_NONNULL((2, 3, 5))
337 const uint8_t *ccder_decode_seqii(cc_size n, cc_unit *r, cc_unit *s, const uint8_t *der, const uint8_t *der_end);
338 
339 /*!
340  @function   ccder_decode_seqii_strict
341  @abstract   Parse a DER sequence of two integers.
342 
343  @param      n        The maximum unit size of the integers.
344  @param      r        First integer output
345  @param      s        Second integer output
346  @param      der      Beginning of input DER buffer
347  @param      der_end  End of input DER buffer
348 
349  @result     Null on error, otherwise a pointer just past the end of the sequence buffer
350  */
351 CC_NONNULL((2, 3, 5))
352 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);
353 
354 CC_NONNULL((1, 3))
355 const uint8_t *ccder_decode_oid(ccoid_t *oidp, const uint8_t *der, const uint8_t *der_end);
356 
357 CC_NONNULL((1, 2, 4))
358 const uint8_t *ccder_decode_bitstring(const uint8_t **bit_string, size_t *bit_length, const uint8_t *der, const uint8_t *der_end);
359 
360 CC_NONNULL((1, 2, 3, 4, 5, 6, 8))
361 const uint8_t *ccder_decode_eckey(uint64_t *version,
362                                   size_t *priv_size,
363                                   const uint8_t **priv_key,
364                                   ccoid_t *oid,
365                                   size_t *pub_size,
366                                   const uint8_t **pub_key,
367                                   const uint8_t *der,
368                                   const uint8_t *der_end);
369 
370 #define CC_EC_OID_SECP192R1                                           \
371     {                                                                 \
372         ((unsigned char *)"\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x01") \
373     }
374 #define CC_EC_OID_SECP256R1                                           \
375     {                                                                 \
376         ((unsigned char *)"\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07") \
377     }
378 #define CC_EC_OID_SECP224R1                               \
379     {                                                     \
380         ((unsigned char *)"\x06\x05\x2B\x81\x04\x00\x21") \
381     }
382 #define CC_EC_OID_SECP384R1                               \
383     {                                                     \
384         ((unsigned char *)"\x06\x05\x2B\x81\x04\x00\x22") \
385     }
386 #define CC_EC_OID_SECP521R1                               \
387     {                                                     \
388         ((unsigned char *)"\x06\x05\x2B\x81\x04\x00\x23") \
389     }
390 
391 #endif /* _CORECRYPTO_CCDER_H_ */
392