1 1.1 christos /* srp-crypto.h 2 1.1 christos * 3 1.1 christos * Copyright (c) 2018-2021 Apple Computer, Inc. All rights reserved. 4 1.1 christos * 5 1.1 christos * Licensed under the Apache License, Version 2.0 (the "License"); 6 1.1 christos * you may not use this file except in compliance with the License. 7 1.1 christos * You may obtain a copy of the License at 8 1.1 christos * 9 1.1 christos * https://www.apache.org/licenses/LICENSE-2.0 10 1.1 christos * 11 1.1 christos * Unless required by applicable law or agreed to in writing, software 12 1.1 christos * distributed under the License is distributed on an "AS IS" BASIS, 13 1.1 christos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 1.1 christos * See the License for the specific language governing permissions and 15 1.1 christos * limitations under the License. 16 1.1 christos * 17 1.1 christos * DNS SIG(0) signature generation for DNSSD SRP using mbedtls. 18 1.1 christos * 19 1.1 christos * Functions required for loading, saving, and generating public/private keypairs, extracting the public key 20 1.1 christos * into KEY RR data, and computing signatures. 21 1.1 christos */ 22 1.1 christos 23 1.1 christos #ifndef __SRP_CRYPTO_H 24 1.1 christos #define __SRP_CRYPTO_H 25 1.1 christos 26 1.1 christos #include "srp.h" 27 1.1 christos 28 1.1 christos // Anonymous key structure, depends on the target. 29 1.1 christos typedef struct srp_key srp_key_t; 30 1.1 christos typedef struct hmac_key hmac_key_t; 31 1.1 christos struct hmac_key { 32 1.1 christos int algorithm; 33 1.1 christos dns_name_t *NONNULL name; 34 1.1 christos uint8_t *NONNULL secret; 35 1.1 christos int length; 36 1.1 christos }; 37 1.1 christos 38 1.1 christos #define ECDSA_KEY_SIZE 64 39 1.1 christos #define ECDSA_KEY_PART_SIZE 32 40 1.1 christos #define ECDSA_SHA256_HASH_SIZE 32 41 1.1 christos #define ECDSA_SHA256_SIG_SIZE 64 42 1.1 christos #define ECDSA_SHA256_SIG_PART_SIZE 32 43 1.1 christos 44 1.1 christos #define SIG_HEADERLEN 11 45 1.1 christos #define SIG_STATIC_RDLEN 18 46 1.1 christos 47 1.1 christos #define dnssec_keytype_ecdsa 13 48 1.1 christos 49 1.1 christos #define SRP_SHA256_DIGEST_SIZE 32 50 1.1 christos #define SRP_SHA256_BLOCK_SIZE 64 51 1.1 christos #define SRP_HMAC_TYPE_SHA256 1 52 1.1 christos 53 1.1 christos #ifdef SRP_CRYPTO_MACOS_INTERNAL 54 1.1 christos #include <CoreFoundation/CoreFoundation.h> 55 1.1 christos #include <Security/Security.h> 56 1.1 christos // #include <Security/SecTransform.h> 57 1.1 christos #include <CoreServices/CoreServices.h> 58 1.1 christos 59 1.1 christos struct srp_key { 60 1.1 christos SecKeyRef NONNULL public; 61 1.1 christos SecKeyRef NONNULL private; 62 1.1 christos }; 63 1.1 christos 64 1.1 christos // An ECDSASHA256 signature in ASN.1 DER format is 0x30 | x | 0x02 | y | r | 0x02 | z | s, where x is the 65 1.1 christos // length of the whole sequence (minus the first byte), y is the encoded length of r, and z is 66 1.1 christos // the encoded length of s. 67 1.1 christos // type offset in output buffer sub-template size of output buffer 68 1.1 christos // ---- ----------------------- ------------ --------------------- 69 1.1 christos #define ECDSA_SIG_TEMPLATE(name) \ 70 1.1 christos static const SecAsn1Template sig_template[] = { \ 71 1.1 christos { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(raw_signature_data_t) }, \ 72 1.1 christos { SEC_ASN1_INTEGER, offsetof(raw_signature_data_t, r), NULL, 0 }, \ 73 1.1 christos { SEC_ASN1_INTEGER, offsetof(raw_signature_data_t, s), NULL, 0 }, \ 74 1.1 christos { 0, 0, NULL, 0 } \ 75 1.1 christos }; 76 1.1 christos 77 1.1 christos #if !TARGET_OS_IPHONE && !TARGET_OS_TV && !TARGET_OS_WATCH 78 1.1 christos #endif // MACOS only 79 1.1 christos #endif // SRP_CRYPTO_MACOS_INTERNAL 80 1.1 christos 81 1.1 christos #ifdef SRP_CRYPTO_MBEDTLS 82 1.1 christos #include <mbedtls/error.h> 83 1.1 christos #include <mbedtls/pk.h> 84 1.1 christos #include <mbedtls/md.h> 85 1.1 christos #include <mbedtls/ecp.h> 86 1.1 christos #include <mbedtls/ecdsa.h> 87 1.1 christos #include <mbedtls/entropy.h> 88 1.1 christos #include <mbedtls/ctr_drbg.h> 89 1.1 christos #include <mbedtls/sha256.h> 90 1.1 christos #include <mbedtls/base64.h> 91 1.1 christos 92 1.1 christos // Works just fine with mbedtls. 93 1.1 christos #define KEYCOPY_WORKS 1 94 1.1 christos 95 1.1 christos // The SRP key includes both the ecdsa key and the pseudo-random number generator context, so that we can 96 1.1 christos // use the PRNG for signing as well as generating keys. The PRNG is seeded with a high-entropy data source. 97 1.1 christos // This structure assumes that we are just using this one key; if we want to support multiple keys then 98 1.1 christos // the entropy source and PRNG should be shared by all keys (of course, that's not thread-safe, so...) 99 1.1 christos struct srp_key { 100 1.1 christos mbedtls_pk_context key; 101 1.1 christos }; 102 1.1 christos 103 1.1 christos // Uncomment the following line to print the data being feed into the hash operation for debugging purpose. 104 1.1 christos // #define DEBUG_SHA256 105 1.1 christos #ifdef DEBUG_SHA256 106 1.1 christos int srp_mbedtls_sha256_update_ret(const char *NONNULL thing_name, 107 1.1 christos mbedtls_sha256_context *NONNULL sha, uint8_t *NONNULL message, size_t msglen); 108 1.1 christos int srp_mbedtls_sha256_finish_ret(mbedtls_sha256_context *NONNULL sha, uint8_t *NONNULL hash); 109 1.1 christos #else 110 1.1 christos #define srp_mbedtls_sha256_update_ret(name, ...) mbedtls_sha256_update_ret(__VA_ARGS__) 111 1.1 christos #define srp_mbedtls_sha256_finish_ret mbedtls_sha256_finish_ret 112 1.1 christos #endif // DEBUG_SHA256 113 1.1 christos #ifdef THREAD_DEVKIT_ADK 114 1.1 christos #define mbedtls_strerror(code, buf, bufsize) snprintf(buf, bufsize, "%d", (int)(code)) 115 1.1 christos #endif 116 1.1 christos 117 1.1 christos // The following entry points must be provided by the host for hosts that use mbedtls signing. 118 1.1 christos 119 1.1 christos // The SRP host is expected to load the SRP-specific host key out of stable storage. 120 1.1 christos // If no key has previously been stored, this function must return kDNSServiceErr_NoSuchKey. 121 1.1 christos // If the key doesn't fit in the buffer, this function must return kDNSServiceErr_NoMemory. 122 1.1 christos // Otherwise, the function is expected to copy the key into the buffer and store the key length 123 1.1 christos // through the length pointer, and return kDNSServiceErr_NoError. 124 1.1 christos int srp_load_key_data(void *NULLABLE host_context, const char *NONNULL key_name, 125 1.1 christos uint8_t *NONNULL buffer, uint16_t *NONNULL length, uint16_t buffer_size); 126 1.1 christos 127 1.1 christos // The SRP host is expected to store the SRP-specific host key in stable storage. 128 1.1 christos // If the key store fails, the server returns a relevant kDNSServiceErr_* error, 129 1.1 christos // such as kDNSServiceErr_NoMemory. Otherwise, the function returns kDNSServiceErr_NoError. 130 1.1 christos // It is generally expected that storing the key will not fail--if it does fail, SRP can't 131 1.1 christos // function. 132 1.1 christos int srp_store_key_data(void *NULLABLE host_context, const char *NONNULL key_name, uint8_t *NONNULL buffer, 133 1.1 christos uint16_t length); 134 1.1 christos 135 1.1 christos int srp_remove_key_file(void *NULLABLE host_context, const char *NONNULL key_name); 136 1.1 christos #endif // SRP_CRYPTO_MBEDTLS 137 1.1 christos 138 1.1 christos // sign_*.c: 139 1.1 christos void srp_keypair_free(srp_key_t *NONNULL key); 140 1.1 christos uint64_t srp_random64(void); 141 1.1 christos uint32_t srp_random32(void); 142 1.1 christos uint16_t srp_random16(void); 143 1.1 christos bool srp_randombytes(uint8_t *NONNULL dest, size_t num); 144 1.1 christos uint8_t srp_key_algorithm(srp_key_t *NONNULL key); 145 1.1 christos size_t srp_pubkey_length(srp_key_t *NONNULL key); 146 1.1 christos size_t srp_signature_length(srp_key_t *NONNULL key); 147 1.1 christos size_t srp_pubkey_copy(uint8_t *NONNULL buf, size_t max, srp_key_t *NONNULL key); 148 1.1 christos int srp_sign(uint8_t *NONNULL output, size_t max, uint8_t *NONNULL message, size_t msglen, 149 1.1 christos uint8_t *NONNULL rdata, size_t rdlen, srp_key_t *NONNULL key); 150 1.1 christos 151 1.1 christos // verify_*.c: 152 1.1 christos bool srp_sig0_verify(dns_wire_t *NONNULL message, dns_rr_t *NONNULL key, dns_rr_t *NONNULL signature); 153 1.1 christos void srp_print_key(srp_key_t *NONNULL key); 154 1.1 christos 155 1.1 christos // hash_*.c: 156 1.1 christos void srp_hmac_iov(hmac_key_t *NONNULL key, uint8_t *NONNULL output, size_t max, struct iovec *NONNULL iov, int count); 157 1.1 christos int srp_base64_parse(char *NONNULL src, size_t *NONNULL len_ret, uint8_t *NONNULL buf, size_t buflen); 158 1.1 christos #endif // __SRP_CRYPTO_H 159 1.1 christos 160 1.1 christos // Local Variables: 161 1.1 christos // mode: C 162 1.1 christos // tab-width: 4 163 1.1 christos // c-file-style: "bsd" 164 1.1 christos // c-basic-offset: 4 165 1.1 christos // fill-column: 108 166 1.1 christos // indent-tabs-mode: nil 167 1.1 christos // End: 168