1/* 2 * Copyright (c) 2012 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24// #define COMMON_DH_FUNCTIONS 25#include "CommonDH.h" 26#include "CommonRandomSPI.h" 27#include <dispatch/dispatch.h> 28#include <dispatch/queue.h> 29#include <corecrypto/ccn.h> 30#include <corecrypto/ccdh.h> 31#include <corecrypto/ccdh_gp.h> 32#include "ccMemory.h" 33#include "ccErrors.h" 34#include "ccGlobals.h" 35#include "ccdebug.h" 36 37typedef struct CCDHParameters_s { 38 ccdh_const_gp_t gp; 39 size_t malloced; 40} CCDHParmSetstruct, *CCDHParmSet; 41 42typedef struct DH_ { 43 CCDHParmSet parms; 44 ccdh_full_ctx_t ctx; 45} CCDHstruct, *CCDH; 46 47 48static void kCCDHRFC2409Group2_storage(void) {} 49static void kCCDHRFC3526Group5_storage(void) {} 50const CCDHParameters kCCDHRFC2409Group2 = (CCDHParameters)&kCCDHRFC2409Group2_storage; 51const CCDHParameters kCCDHRFC3526Group5 = (CCDHParameters)&kCCDHRFC3526Group5_storage; 52 53CCDHRef 54CCDHCreate(CCDHParameters dhParameter) 55{ 56 CCDHParmSet CCDHParm = (CCDHParmSet)dhParameter; 57 CCDHParmSet stockParm = NULL; 58 CCDH retval = NULL; 59 size_t retSize = 0; 60 61 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 62 CC_NONULLPARMRETNULL(dhParameter); 63 if (dhParameter == kCCDHRFC2409Group2) { 64 return NULL; 65 } else if (dhParameter == kCCDHRFC3526Group5) { 66 stockParm = CC_XMALLOC(sizeof(CCDHParmSetstruct)); 67 stockParm->gp = ccdh_gp_rfc3526group05(); 68 stockParm->malloced = true; 69 CCDHParm = stockParm; 70 } else { 71 } 72 73 retval = CC_XMALLOC(sizeof(CCDHstruct)); 74 if(retval == NULL) goto error; 75 76 retSize = ccdh_full_ctx_size(ccdh_ccn_size(CCDHParm->gp)); 77 retval->ctx._full = CC_XMALLOC(retSize); 78 79 if(retval->ctx._full == NULL) goto error; 80 ccdh_ctx_init(CCDHParm->gp, retval->ctx); 81 retval->parms = CCDHParm; 82 83 return (CCDHRef) retval; 84 85error: 86 if(stockParm) CC_XFREE(stockParm, sizeof(CCDHParmSetstruct)); 87 if(retval) CC_XFREE(retval, retSize); 88 return NULL; 89} 90 91void 92CCDHRelease(CCDHRef ref) 93{ 94 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 95 if(ref == NULL) return; 96 CCDH keyref = (CCDH) ref; 97 if(keyref->ctx._full) 98 CC_XFREE(keyref->ctx._full, ccdh_full_ctx_size(ccdh_ccn_size(keyref->parms->gp))); 99 keyref->ctx._full = NULL; 100 keyref->parms = NULL; 101 CC_XFREE(keyref, sizeof(CCDHstruct)); 102} 103 104int 105CCDHGenerateKey(CCDHRef ref, void *output, size_t *outputLength) 106{ 107 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 108 CC_NONULLPARM(ref); 109 CC_NONULLPARM(output); 110 CC_NONULLPARM(outputLength); 111 112 CCDH keyref = (CCDH) ref; 113 114 if(ccdh_generate_key(keyref->parms->gp, ccDRBGGetRngState(), keyref->ctx.pub)) 115 return -1; 116 117 size_t size_needed = ccdh_export_pub_size(keyref->ctx); 118 if(size_needed > *outputLength) { 119 *outputLength = size_needed; 120 return -1; 121 } 122 123 *outputLength = size_needed; 124 ccdh_export_pub(keyref->ctx, output); 125 return 0; 126} 127 128 129int 130CCDHComputeKey(unsigned char *sharedKey, size_t *sharedKeyLen, const void *peerPubKey, size_t peerPubKeyLen, CCDHRef ref) 131{ 132 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 133 CC_NONULLPARM(sharedKey); 134 CC_NONULLPARM(sharedKeyLen); 135 CC_NONULLPARM(peerPubKey); 136 CC_NONULLPARM(ref); 137 138 CCDH keyref = (CCDH) ref; 139 ccdh_pub_ctx_decl_gp(keyref->parms->gp, peer_pub); 140 cc_size n = ccdh_ctx_n(keyref->ctx); 141 cc_unit skey[n]; 142 143 if(ccdh_import_pub(keyref->parms->gp, peerPubKeyLen, peerPubKey, 144 peer_pub)) 145 return -1; 146 147 if(ccdh_compute_key(keyref->ctx, peer_pub, skey)) 148 return -1; 149 150 size_t size_needed = ccn_write_uint_size(n, skey); 151 if(size_needed > *sharedKeyLen) { 152 *sharedKeyLen = size_needed; 153 return -1; 154 } 155 *sharedKeyLen = size_needed; 156 (void) ccn_write_uint_padded(n, skey, *sharedKeyLen, sharedKey); 157 158 return 0; 159 160} 161 162CCDHParameters 163CCDHParametersCreateFromData(const void *p, size_t pLen, const void *g, size_t gLen, size_t l) 164{ 165 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 166 CC_NONULLPARMRETNULL(p); 167 CC_NONULLPARMRETNULL(g); 168 169 cc_size psize = ccn_nof_size(pLen); 170 cc_size gsize = ccn_nof_size(gLen); 171 cc_size n = (psize > gsize) ? psize: gsize; 172 cc_unit pval[n], gval[n]; 173 174 CCDHParmSet retval = CC_XMALLOC(sizeof(CCDHParmSetstruct)); 175 if(!retval) goto error; 176 177 retval->malloced = ccdh_gp_size(n); 178 retval->gp.gp = (ccdh_gp *) CC_XMALLOC(retval->malloced); 179 if(!retval->gp.gp) goto error; 180 if(ccdh_init_gp(retval->gp._ncgp, n, pval, gval, (cc_size) l)) 181 goto error; 182 return retval; 183error: 184 if(retval && retval->gp.gp) CC_XFREE((ccdh_gp *) retval->gp.gp, retval->malloced); 185 if(retval) CC_XFREE(retval, sizeof(CCDHParmSetstruct)); 186 return NULL; 187} 188 189void 190CCDHParametersRelease(CCDHParameters parameters) 191{ 192 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 193 if(parameters == NULL) return; 194 if(parameters == kCCDHRFC2409Group2) return; 195 if(parameters == kCCDHRFC3526Group5) return; 196 197 CCDHParmSet CCDHParm = (CCDHParmSet) parameters; 198 if(CCDHParm->malloced) { 199 CC_XFREE((void *) parameters->gp.gp, retval->malloced); 200 } 201 CCDHParm->malloced = 0; 202 CCDHParm->gp.gp = NULL; 203 CC_XFREE(CCDHParm, sizeof(CCDHParmSetstruct)); 204} 205 206// TODO - needs PKCS3 in/out 207CCDHParameters 208CCDHParametersCreateFromPKCS3(const void *data, size_t len) 209{ 210 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 211 CC_NONULLPARMRETNULL(data); 212 return NULL; 213} 214 215size_t 216CCDHParametersPKCS3EncodeLength(CCDHParameters parms) 217{ 218 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 219 return 0; 220} 221 222size_t 223CCDHParametersPKCS3Encode(CCDHParameters parms, void *data, size_t dataAvailable) 224{ 225 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 226 return 0; 227} 228 229