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