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