OSStatus SecDHCreate(uint32_t g, const uint8_t *p, size_t p_len, uint32_t l, const uint8_t *recip, size_t recip_len, SecDHContext *pdh) { cc_size n = ccn_nof_size(p_len); size_t context_size = SecDH_context_size(p_len); void *context = malloc(context_size); bzero(context, context_size); ccdh_gp_t gp; gp.gp = context; CCDH_GP_N(gp) = n; CCDH_GP_L(gp) = l; if(ccn_read_uint(n, CCDH_GP_PRIME(gp), p_len, p)) goto errOut; if(recip) { if(ccn_read_uint(n+1, CCDH_GP_RECIP(gp), recip_len, recip)) goto errOut; CCZP_MOD_PRIME(gp.zp) = cczp_mod; } else { cczp_init(gp.zp); }; ccn_seti(n, CCDH_GP_G(gp), g); *pdh = (SecDHContext) context; return errSecSuccess; errOut: SecDHDestroy(context); *pdh = NULL; return errSecInternal; }
OSStatus SecDHCreateFromParameters(const uint8_t *params, size_t params_len, SecDHContext *pdh) { DERReturn drtn; DERItem paramItem = {(DERByte *)params, params_len}; DER_DHParams decodedParams; uint32_t l; drtn = DERParseSequence(¶mItem, DER_NumDHParamsItemSpecs, DER_DHParamsItemSpecs, &decodedParams, sizeof(decodedParams)); if(drtn) return drtn; drtn = DERParseInteger(&decodedParams.l, &l); if(drtn) return drtn; cc_size n = ccn_nof_size(decodedParams.p.length); cc_size p_len = ccn_sizeof_n(n); size_t context_size = ccdh_gp_size(p_len)+ccdh_full_ctx_size(p_len); void *context = malloc(context_size); if(context==NULL) return errSecAllocate; bzero(context, context_size); ccdh_gp_t gp; gp.gp = context; CCDH_GP_N(gp) = n; CCDH_GP_L(gp) = l; if(ccn_read_uint(n, CCDH_GP_PRIME(gp), decodedParams.p.length, decodedParams.p.data)) goto errOut; if(decodedParams.recip.length) { if(ccn_read_uint(n+1, CCDH_GP_RECIP(gp), decodedParams.recip.length, decodedParams.recip.data)) goto errOut; gp.zp.zp->mod_prime = cczp_mod; } else { cczp_init(gp.zp); }; if(ccn_read_uint(n, CCDH_GP_G(gp), decodedParams.g.length, decodedParams.g.data)) goto errOut; *pdh = (SecDHContext) context; return errSecSuccess; errOut: SecDHDestroy(context); *pdh = NULL; return errSecInvalidKey; }
OSStatus SecDHCreateFromParameters(const uint8_t *params, size_t params_len, SecDHContext *pdh) { // We support DomainParameters as specified in PKCS#3 // (http://www.emc.com/emc-plus/rsa-labs/standards-initiatives/pkcs-3-diffie-hellman-key-agreement-standar.htm) // DHParameter ::= SEQUENCE { // prime INTEGER, -- p // base INTEGER, -- g // privateValueLength INTEGER OPTIONAL } DERReturn drtn; DERItem paramItem = {(DERByte *)params, params_len}; DER_DHParams decodedParams; uint32_t l = 0; drtn = DERParseSequence(¶mItem, DER_NumDHParamsItemSpecs, DER_DHParamsItemSpecs, &decodedParams, sizeof(decodedParams)); if(drtn) return drtn; if (decodedParams.l.length > 0) { drtn = DERParseInteger(&decodedParams.l, &l); if(drtn) return drtn; } cc_size n = ccn_nof_size(decodedParams.p.length); cc_size p_len = ccn_sizeof_n(n); size_t context_size = ccdh_gp_size(p_len)+ccdh_full_ctx_size(p_len); void *context = malloc(context_size); if(context==NULL) return errSecAllocate; bzero(context, context_size); ccdh_gp_t gp; gp.gp = context; CCDH_GP_N(gp) = n; CCDH_GP_L(gp) = l; if(ccn_read_uint(n, CCDH_GP_PRIME(gp), decodedParams.p.length, decodedParams.p.data)) goto errOut; if(decodedParams.recip.length) { if(ccn_read_uint(n+1, CCDH_GP_RECIP(gp), decodedParams.recip.length, decodedParams.recip.data)) goto errOut; CCZP_MOD_PRIME(gp.zp) = cczp_mod; } else { cczp_init(gp.zp); }; if(ccn_read_uint(n, CCDH_GP_G(gp), decodedParams.g.length, decodedParams.g.data)) goto errOut; *pdh = (SecDHContext) context; return errSecSuccess; errOut: SecDHDestroy(context); *pdh = NULL; return errSecInvalidKey; }