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