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(&paramItem,
                            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;
}
static inline ccdh_full_ctx_t SecDH_priv(SecDHContext dh)
{
    void *p = dh;
    cczp_t zp = { .u = p };
    cc_size s = ccn_sizeof_n(cczp_n(zp));
    ccdh_full_ctx_t priv = { .hdr = (struct ccdh_ctx_header *)(p+ccdh_gp_size(s)) };
    return priv;
}

static inline size_t SecDH_context_size(size_t p_len)
{
    cc_size n = ccn_nof_size(p_len);
    cc_size real_p_len = ccn_sizeof_n(n);
    size_t context_size = ccdh_gp_size(real_p_len)+ccdh_full_ctx_size(real_p_len);
    return context_size;
}
Beispiel #3
0
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(&paramItem,
                            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;
}