Home | History | Annotate | Line # | Download | only in utilities
      1 /*
      2  * Copyright (c) 2022 Apple Inc. All rights reserved.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     https://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef DNS_OBJ_CRYPTO_H
     18 #define DNS_OBJ_CRYPTO_H
     19 
     20 //======================================================================================================================
     21 // MARK: - Headers
     22 
     23 #include "dns_common.h"
     24 #include <stdint.h>
     25 #include <stdbool.h>
     26 
     27 #ifdef __APPLE__
     28 #include <CommonCrypto/CommonDigestSPI.h>
     29 #endif
     30 
     31 #include "dns_assert_macros.h"
     32 #include "nullability.h"
     33 
     34 //======================================================================================================================
     35 // MARK: - Constants
     36 
     37 #ifndef SHA1_OUTPUT_SIZE
     38 
     39 // Digest constants.
     40 typedef enum digest_type {
     41 	DIGEST_UNSUPPORTED,
     42 	DIGEST_SHA_1,
     43 	DIGEST_SHA_256,
     44 	DIGEST_SHA_384,
     45 	DIGEST_SHA_512
     46 } digest_type_t;
     47 
     48 #define SHA1_OUTPUT_SIZE		20
     49 #define SHA256_OUTPUT_SIZE		32
     50 #define SHA384_OUTPUT_SIZE		48
     51 #define SHA512_OUTPUT_SIZE		64
     52 #ifndef MAX_DIGEST_OUTPUT_SIZE
     53 #define MAX_DIGEST_OUTPUT_SIZE	SHA512_OUTPUT_SIZE
     54 #endif
     55 
     56 check_compile_time(SHA512_OUTPUT_SIZE	<= MAX_DIGEST_OUTPUT_SIZE);
     57 check_compile_time(SHA384_OUTPUT_SIZE	<= MAX_DIGEST_OUTPUT_SIZE);
     58 check_compile_time(SHA1_OUTPUT_SIZE		<= MAX_DIGEST_OUTPUT_SIZE);
     59 check_compile_time(SHA256_OUTPUT_SIZE	<= MAX_DIGEST_OUTPUT_SIZE);
     60 
     61 #define MAX_HASHED_NAME_INPUT_SIZE	(MAX_DOMAIN_NAME + UINT8_MAX)
     62 #define MAX_HASHED_NAME_OUTPUT_SIZE	MAX_DIGEST_OUTPUT_SIZE
     63 #define MAX_HASHED_NAME_BUFF_SIZE	(MAX(MAX_HASHED_NAME_INPUT_SIZE, MAX_HASHED_NAME_OUTPUT_SIZE))
     64 
     65 //======================================================================================================================
     66 // Signature verification constants.
     67 
     68 #define MAX_PUBLIC_KEY_BYTES		RSA_PUBLIC_MAX_KEY_BYTES
     69 #define MAX_SECRET_KEY_BYTES		RSA_SECRET_MAX_KEY_BYTES
     70 #define MAX_SIGNATURE_BYTES			RSA_SIGNATURE_BYTES
     71 
     72 // RSA
     73 #define RSA_PUBLIC_MAX_KEY_BYTES	260
     74 #define RSA_SECRET_MAX_KEY_BYTES	1190
     75 #define RSA_SIGNATURE_BYTES			256
     76 check_compile_time(MAX_PUBLIC_KEY_BYTES	>= RSA_PUBLIC_MAX_KEY_BYTES);
     77 check_compile_time(MAX_SECRET_KEY_BYTES	>= RSA_SECRET_MAX_KEY_BYTES);
     78 check_compile_time(MAX_SIGNATURE_BYTES	>= RSA_SIGNATURE_BYTES);
     79 
     80 // ECDSAP
     81 #define ECDSAP_PUBLIC_KEY_BYTES		64
     82 #define ECDSAP_SECRET_KEY_BYTES		96
     83 #define ECDSAP_SIGNATURE_BYTES		64
     84 check_compile_time(MAX_PUBLIC_KEY_BYTES	>= ECDSAP_PUBLIC_KEY_BYTES);
     85 check_compile_time(MAX_SECRET_KEY_BYTES	>= ECDSAP_SECRET_KEY_BYTES);
     86 check_compile_time(MAX_SIGNATURE_BYTES	>= ECDSAP_SIGNATURE_BYTES);
     87 
     88 // ED25519
     89 #define ED25519_PUBLIC_KEY_BYTES	32
     90 #define ED25519_SECRET_KEY_BYTES	32
     91 #define ED25519_SIGNATURE_BYTES		64
     92 check_compile_time(MAX_PUBLIC_KEY_BYTES	>= ED25519_PUBLIC_KEY_BYTES);
     93 check_compile_time(MAX_SECRET_KEY_BYTES	>= ED25519_SECRET_KEY_BYTES);
     94 check_compile_time(MAX_SIGNATURE_BYTES	>= ED25519_SIGNATURE_BYTES);
     95 
     96 // ED448
     97 #define ED448_PUBLIC_KEY_BYTES		57
     98 #define ED448_SECRET_KEY_BYTES		57
     99 #define ED448_SIGNATURE_BYTES		114
    100 check_compile_time(MAX_PUBLIC_KEY_BYTES	>= ED448_PUBLIC_KEY_BYTES);
    101 check_compile_time(MAX_SECRET_KEY_BYTES	>= ED448_SECRET_KEY_BYTES);
    102 check_compile_time(MAX_SIGNATURE_BYTES	>= ED448_SIGNATURE_BYTES);
    103 
    104 #endif // #ifndef SHA1_OUTPUT_SIZE
    105 
    106 //======================================================================================================================
    107 // MARK: - Structs
    108 
    109 typedef struct dns_obj_digest_ctx_s {
    110 #ifdef __APPLE__
    111 	CCDigestCtx ctx;
    112 #else
    113 	uint8_t _dummy_ctx;
    114 #endif
    115 } dns_obj_digest_ctx_t;
    116 
    117 //======================================================================================================================
    118 // MARK: - Function Declarations
    119 
    120 /*!
    121  *	@brief
    122  *		Initialize the digest context and get it ready for updating the digest.
    123  *
    124  *	@param context
    125  *		The digest context.
    126  *
    127  *	@param digest_type
    128  *		The digest type that would be calculated, including:
    129  *			DIGEST_SHA_1
    130  *			DIGEST_SHA_256
    131  *			DIGEST_SHA_384
    132  *			DIGEST_SHA_512
    133  *
    134  *	@result
    135  *		DNS_OBJ_ERROR_NO_ERROR if no error occurs, otherwise, the corresponding error encountered when doing initialization.
    136  */
    137 dns_obj_error_t
    138 dns_obj_data_compute_digest_init(dns_obj_digest_ctx_t * NONNULL context, digest_type_t digest_type);
    139 
    140 /*!
    141  *	@brief
    142  *		Append more data to generate the final digest output.
    143  *
    144  *	@param context
    145  *		The context that has been initialized by <code>data_compute_digest_init()</code>.
    146  *
    147  *	@param length
    148  *		 The length of the data passed in bytes.
    149  *
    150  *	@result
    151  *		DNS_OBJ_ERROR_NO_ERROR if no error occurs, otherwise, the corresponding error encountered when doing initialization.
    152  */
    153 dns_obj_error_t
    154 dns_obj_data_compute_digest_update(dns_obj_digest_ctx_t * NONNULL context, const uint8_t * NONNULL data, size_t length);
    155 
    156 /*!
    157  *	@brief
    158  *		Get the digest result of all data that has been updated with <code>data_compute_digest_update()</code>.
    159  *
    160  *	@param context
    161  *		The context that has been fed with the data to calculate the digest.
    162  *
    163  *	@param out_digest
    164  *		The digest output of the data for the specific digest type.
    165  *
    166  *	@result
    167  *		DNS_OBJ_ERROR_NO_ERROR if no error occurs, otherwise, the corresponding error encountered when doing initialization.
    168  */
    169 dns_obj_error_t
    170 dns_obj_data_compute_digest_final(dns_obj_digest_ctx_t * NONNULL context, uint8_t * NONNULL out_digest);
    171 
    172 /*!
    173  *	@brief
    174  *		Get the digest length of the specific digest type.
    175  *
    176  *	@param digest_type
    177  *		The type of the digest, including:
    178  *			DIGEST_SHA_1
    179  *			DIGEST_SHA_256
    180  *			DIGEST_SHA_384
    181  *			DIGEST_SHA_512
    182  *
    183  *	@result
    184  *		The size of the digest.
    185  */
    186 size_t
    187 dns_obj_data_compute_digest_get_output_size(digest_type_t digest_type);
    188 
    189 /*!
    190  *	@brief
    191  *		Reset the context to compute a new digest for a new data.
    192  *
    193  *	@param context
    194  *		The digest context.
    195  */
    196 void
    197 dns_obj_data_compute_digest_reset(dns_obj_digest_ctx_t * NONNULL context);
    198 
    199 /*!
    200  *	@brief
    201  *		Compute the digest of the data in one shot.
    202  *
    203  *	@param digest_type
    204  *		The type of the digest to compute.
    205  *
    206  *	@param data
    207  *		The pointer to the data bytes.
    208  *
    209  *	@param data_len
    210  *		The length of the data.
    211  *
    212  *	@param out_digest
    213  *		The pointer to the buffer that stores the digest output.
    214  *
    215  *	@param out_error
    216  *		The pointer to the error value indicates the success of the function call or the error encountered.
    217  */
    218 void
    219 dns_obj_data_compute_digest(digest_type_t digest_type, const uint8_t * NONNULL data, size_t data_len,
    220 	uint8_t * NONNULL out_digest, dns_obj_error_t * NULLABLE out_error);
    221 
    222 /*!
    223  *	@brief
    224  *		Compute the digest used by NSEC3 resource record to hash a domain name.
    225  *
    226  *	@param digest_type
    227  *		The type of the digest to compute, currently NSEC3 only uses DIGEST_SHA_1.
    228  *
    229  *	@param data
    230  *		The data to compute the digest.
    231  *
    232  *	@param data_length
    233  *		The length of the data above.
    234  *
    235  *	@param iterations
    236  *		The extra iterations of the digest calculation.
    237  *
    238  *	@param salt
    239  *		The salt to append when calculating the digest for each iteration.
    240  *
    241  *	@param salt_length
    242  *		The length of the salt above.
    243  *
    244  *	@param out_digest
    245  *		The buffer where the digest will be stored as the output.
    246  *
    247  *	@result
    248  *		DNS_OBJ_ERROR_NO_ERROR if no error occurs, otherwise, the corresponding error encountered during the calculation.
    249  */
    250 dns_obj_error_t
    251 dns_obj_compute_nsec3_digest(digest_type_t digest_type, const uint8_t * NONNULL data, size_t data_length,
    252 	uint16_t iterations, const uint8_t * NULLABLE salt, uint8_t salt_length, uint8_t * NONNULL out_digest);
    253 
    254 /*!
    255  *	@brief
    256  *		Verify the DNSSEC signature of the data given the public key.
    257  *
    258  *	@param data
    259  *		The pointer to the data bytes to be verified.
    260  *
    261  *	@param data_len
    262  *		The length of the data bytes.
    263  *
    264  *	@param algorithm
    265  *		The algorithm used to generate the signature.
    266  *
    267  *	@param key
    268  *		The public key in bytes.
    269  *
    270  *	@param key_size
    271  *		The size of the public key.
    272  *
    273  *	@param signature
    274  *		The pointer to the signature bytes.
    275  *
    276  *	@param signature_len
    277  *		The length of the signature.
    278  *
    279  *	@param out_error
    280  *		The pointer to the error value indicates the success of the validation call or the cause of the validation failure.
    281  *
    282  *	@result
    283  *		True if the signature matches, otherwise, false.
    284  */
    285 bool
    286 dns_obj_dnssec_signature_verify(const uint8_t * NONNULL data, size_t data_len, uint8_t algorithm,
    287 	const uint8_t * NONNULL key, size_t key_size, const uint8_t * NONNULL signature, size_t signature_len,
    288 	dns_obj_error_t * NULLABLE out_error);
    289 
    290 #endif // DNS_OBJ_CRYPTO_H
    291