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