1/* 2 * Copyright (c) 2006 - 2010 Kungliga Tekniska Högskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Portions Copyright (c) 2010 Apple Inc. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36#include <config.h> 37 38#ifdef HEIM_HC_SF 39 40#include <stdio.h> 41#include <stdlib.h> 42#include <dh.h> 43 44#include <roken.h> 45 46#include <rfc2459_asn1.h> 47 48#include <Security/SecDH.h> 49 50#include "common.h" 51 52struct dh_sf { 53 SecDHContext secdh; 54}; 55 56#define DH_NUM_TRIES 10 57 58static int 59sf_dh_generate_key(DH *dh) 60{ 61 struct dh_sf *sf = DH_get_ex_data(dh, 0); 62 size_t length, size = 0; 63 DHParameter dp; 64 void *data = NULL; 65 int ret; 66 67 if (dh->p == NULL || dh->g == NULL) 68 return 0; 69 70 memset(&dp, 0, sizeof(dp)); 71 72 ret = _hc_BN_to_integer(dh->p, &dp.prime); 73 if (ret == 0) 74 ret = _hc_BN_to_integer(dh->g, &dp.base); 75 if (ret) { 76 free_DHParameter(&dp); 77 return 0; 78 } 79 dp.privateValueLength = NULL; 80 81 ASN1_MALLOC_ENCODE(DHParameter, data, length, &dp, &size, ret); 82 free_DHParameter(&dp); 83 if (ret) 84 return 0; 85 if (size != length) 86 abort(); 87 88 if (sf->secdh) { 89 SecDHDestroy(sf->secdh); 90 sf->secdh = NULL; 91 } 92 93 ret = SecDHCreateFromParameters(data, length, &sf->secdh); 94 if (ret) 95 goto error; 96 97 free(data); 98 data = NULL; 99 100 length = BN_num_bytes(dh->p); 101 data = malloc(size); 102 if (data == NULL) 103 goto error; 104 105 ret = SecDHGenerateKeypair(sf->secdh, data, &length); 106 if (ret) 107 goto error; 108 109 dh->pub_key = BN_bin2bn(data, length, NULL); 110 if (dh->pub_key == NULL) 111 goto error; 112 113 free(data); 114 115 return 1; 116 117 error: 118 if (data) 119 free(data); 120 if (sf->secdh) 121 SecDHDestroy(sf->secdh); 122 sf->secdh = NULL; 123 124 return 1; 125} 126 127static int 128sf_dh_compute_key(unsigned char *shared, const BIGNUM * pub, DH *dh) 129{ 130 struct dh_sf *sf = DH_get_ex_data(dh, 0); 131 size_t length, shared_length; 132 OSStatus ret; 133 void *data; 134 135 shared_length = BN_num_bytes(dh->p); 136 137 length = BN_num_bytes(pub); 138 data = malloc(length); 139 if (data == NULL) 140 return 0; 141 142 BN_bn2bin(pub, data); 143 144 ret = SecDHComputeKey(sf->secdh, data, length, shared, &shared_length); 145 free(data); 146 if (ret) 147 return 0; 148 149 return shared_length; 150} 151 152 153static int 154sf_dh_generate_params(DH *dh, int a, int b, BN_GENCB *callback) 155{ 156 return 0; 157} 158 159static int 160sf_dh_init(DH *dh) 161{ 162 struct dh_sf *sf; 163 164 sf = calloc(1, sizeof(*sf)); 165 if (sf == NULL) 166 return 0; 167 168 DH_set_ex_data(dh, 0, sf); 169 170 return 1; 171} 172 173static int 174sf_dh_finish(DH *dh) 175{ 176 struct dh_sf *sf = DH_get_ex_data(dh, 0); 177 178 if (sf->secdh) 179 SecDHDestroy(sf->secdh); 180 free(sf); 181 182 return 1; 183} 184 185 186/* 187 * 188 */ 189 190const DH_METHOD _hc_dh_sf_method = { 191 "hcrypto sf DH", 192 sf_dh_generate_key, 193 sf_dh_compute_key, 194 NULL, 195 sf_dh_init, 196 sf_dh_finish, 197 0, 198 NULL, 199 sf_dh_generate_params 200}; 201 202/** 203 * DH implementation using SecurityFramework 204 * 205 * @return the DH_METHOD for the DH implementation using SecurityFramework. 206 * 207 * @ingroup hcrypto_dh 208 */ 209 210const DH_METHOD * 211DH_sf_method(void) 212{ 213 return &_hc_dh_sf_method; 214} 215#endif /* HEIM_HC_SF */ 216