Home | History | Annotate | Line # | Download | only in ServiceRegistration
      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