mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-02-09 17:26:03 +00:00
Thanks to Travis Cross for pushing for this to happen. Signed-off-by: Philip Zimmermann <prz@mit.edu> Signed-off-by: Travis Cross <tc@traviscross.com>
643 lines
19 KiB
C
643 lines
19 KiB
C
/*
|
|
* libZRTP SDK library, implements the ZRTP secure VoIP protocol.
|
|
* Copyright (c) 2006-2009 Philip R. Zimmermann. All rights reserved.
|
|
* Contact: http://philzimmermann.com
|
|
* For licensing and other legal details, see the file zrtp_legal.c.
|
|
*/
|
|
|
|
#include "zrtp.h"
|
|
|
|
/* We don't have digital signatures ready yet. */
|
|
#if 0
|
|
|
|
/* Size of extra random data to approximate a uniform distribution mod n */
|
|
#define UNIFORMBYTES 8
|
|
|
|
/*============================================================================*/
|
|
/* Shared Elliptic Curve functions */
|
|
/* */
|
|
/* The Elliptic Curve DSA algorithm, key generation, and curves are */
|
|
/* from FIPS 186-3. The curves used are */
|
|
/* also defined in RFC 4753, sections 3.1 through 3.3. */
|
|
/*============================================================================*/
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
/* Return dsa_cc->pv holding public value and dsa_cc->sv holding secret value */
|
|
/* The public value is an elliptic curve point encoded as the x part shifted */
|
|
/* left Pbits bits and or'd with the y part. */
|
|
/*----------------------------------------------------------------------------*/
|
|
static zrtp_status_t ECDSA_keygen( struct zrtp_sig_scheme *self,
|
|
zrtp_dsa_crypto_context_t *dsa_cc,
|
|
zrtp_ec_params_t *ec_params,
|
|
#ifdef ZRTP_TEST_VECTORS
|
|
uint8_t *sv_data, size_t sv_data_len,
|
|
uint8_t *pvx_data, size_t pvx_data_len,
|
|
uint8_t *pvy_data, size_t pvy_data_len,
|
|
#endif
|
|
unsigned Pbits )
|
|
{
|
|
zrtp_status_t s = zrtp_status_fail;
|
|
struct BigNum P, Gx, Gy, n;
|
|
struct BigNum pkx, pky;
|
|
unsigned ec_bytes;
|
|
|
|
if (!ec_params)
|
|
return zrtp_status_bad_param;
|
|
|
|
ec_bytes = (ec_params->ec_bits+7) / 8;
|
|
|
|
do
|
|
{
|
|
if (!self || !dsa_cc)
|
|
{
|
|
s = zrtp_status_bad_param;
|
|
break;
|
|
}
|
|
|
|
bnBegin(&P);
|
|
bnInsertBigBytes( &P, ec_params->P_data, 0, ec_bytes );
|
|
bnBegin(&Gx);
|
|
bnInsertBigBytes( &Gx, ec_params->Gx_data, 0, ec_bytes );
|
|
bnBegin(&Gy);
|
|
bnInsertBigBytes( &Gy, ec_params->Gy_data, 0, ec_bytes );
|
|
bnBegin(&n);
|
|
bnInsertBigBytes( &n, ec_params->n_data, 0, ec_bytes );
|
|
|
|
bnBegin(&pkx);
|
|
bnBegin(&pky);
|
|
bnBegin(&dsa_cc->sv);
|
|
s = zrtp_ec_random_point( self->base.zrtp_global, &P, &n, &Gx, &Gy,
|
|
#ifdef ZRTP_TEST_VECTORS
|
|
sv_data, sv_data_len,
|
|
pvx_data, pvx_data_len,
|
|
pvy_data, pvy_data_len,
|
|
#endif
|
|
&pkx, &pky, &dsa_cc->sv );
|
|
if ( s != zrtp_status_ok )
|
|
break;
|
|
s = zrtp_status_fail;
|
|
|
|
bnBegin(&dsa_cc->pv);
|
|
bnCopy (&dsa_cc->pv, &pkx);
|
|
bnLShift (&dsa_cc->pv, Pbits);
|
|
bnAdd (&dsa_cc->pv, &pky);
|
|
bnEnd (&pkx);
|
|
bnEnd (&pky);
|
|
bnEnd (&P);
|
|
bnEnd (&Gx);
|
|
bnEnd (&Gy);
|
|
bnEnd (&n);
|
|
|
|
s = zrtp_status_ok;
|
|
} while (0);
|
|
|
|
return s;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
/* Sign the specified hash value - must be size matching the curve */
|
|
/*----------------------------------------------------------------------------*/
|
|
static zrtp_status_t ECDSA_sign( struct zrtp_sig_scheme *self,
|
|
zrtp_dsa_crypto_context_t *dsa_cc,
|
|
zrtp_ec_params_t *ec_params,
|
|
#ifdef ZRTP_TEST_VECTORS
|
|
uint8_t *k_data, size_t k_data_len,
|
|
uint8_t *rx_data, size_t rx_data_len,
|
|
uint8_t *ry_data, size_t ry_data_len,
|
|
uint8_t *s_data, size_t s_data_len,
|
|
#endif
|
|
uint8_t *hash, uint32_t hash_len,
|
|
struct BigNum *dsasig )
|
|
{
|
|
zrtp_status_t s = zrtp_status_fail;
|
|
struct BigNum P, Gx, Gy, n;
|
|
struct BigNum h, s1, k, rx, ry, kinv, pkx, pky;
|
|
unsigned ec_bytes;
|
|
|
|
if (!ec_params)
|
|
return zrtp_status_bad_param;
|
|
|
|
ec_bytes = (ec_params->ec_bits+7) / 8;
|
|
|
|
do
|
|
{
|
|
if (!self || !dsa_cc)
|
|
{
|
|
s = zrtp_status_bad_param;
|
|
break;
|
|
}
|
|
|
|
bnBegin(&P);
|
|
bnInsertBigBytes( &P, ec_params->P_data, 0, ec_bytes );
|
|
bnBegin(&Gx);
|
|
bnInsertBigBytes( &Gx, ec_params->Gx_data, 0, ec_bytes );
|
|
bnBegin(&Gy);
|
|
bnInsertBigBytes( &Gy, ec_params->Gy_data, 0, ec_bytes );
|
|
bnBegin(&n);
|
|
bnInsertBigBytes( &n, ec_params->n_data, 0, ec_bytes );
|
|
|
|
/* Hash to bignum */
|
|
bnBegin(&h);
|
|
bnInsertBigBytes( &h, hash, 0, hash_len );
|
|
bnMod (&h, &h, &P);
|
|
|
|
/* Unpack signing key */
|
|
bnBegin(&pkx);
|
|
bnBegin(&pky);
|
|
bnSetQ (&pkx, 1);
|
|
bnLShift (&pkx, ec_bytes*8);
|
|
bnMod (&pky, &dsa_cc->pv, &pkx);
|
|
bnCopy (&pkx, &dsa_cc->pv);
|
|
bnRShift (&pkx, ec_bytes*8);
|
|
|
|
/* Choose signature secret k value */
|
|
bnBegin(&rx);
|
|
bnBegin(&ry);
|
|
bnBegin(&k);
|
|
s = zrtp_ec_random_point( self->base.zrtp_global, &P, &n, &Gx, &Gy,
|
|
#ifdef ZRTP_TEST_VECTORS
|
|
k_data, k_data_len,
|
|
rx_data, rx_data_len,
|
|
ry_data, ry_data_len,
|
|
#endif
|
|
&rx, &ry, &k );
|
|
if ( s != zrtp_status_ok )
|
|
break;
|
|
s = zrtp_status_fail;
|
|
|
|
#ifndef ZRTP_TEST_VECTORS
|
|
/* For further randomness we are going to add the secret key to k */
|
|
bnAddMod_ (&k, &dsa_cc->sv, &n);
|
|
zrtp_ecAdd (&rx, &ry, &rx, &ry, &pkx, &pky, &P);
|
|
#endif
|
|
|
|
/* Perform the signature */
|
|
bnBegin (&s1);
|
|
bnMulMod_ (&s1, &rx, &dsa_cc->sv, &n);
|
|
bnAddMod_ (&s1, &h, &n);
|
|
bnBegin (&kinv);
|
|
bnInv (&kinv, &k, &n);
|
|
bnMulMod_ (&s1, &s1, &kinv, &n);
|
|
|
|
#ifdef ZRTP_TEST_VECTORS
|
|
if (k_data_len != 0)
|
|
{
|
|
/* rx is checked in ec_random_point */
|
|
struct BigNum s2;
|
|
int ok;
|
|
bnBegin(&s2);
|
|
bnInsertBigBytes(&s2, s_data, 0, s_data_len);
|
|
ok = (bnCmp (&s1, &s2) == 0);
|
|
bnEnd(&s2);
|
|
if (!ok)
|
|
break;
|
|
}
|
|
#endif
|
|
|
|
/* Combine r, s into dsasig */
|
|
bnBegin(dsasig);
|
|
bnCopy (dsasig, &rx);
|
|
bnLShift (dsasig, ec_bytes*8);
|
|
bnAdd (dsasig, &s1);
|
|
bnEnd (&rx);
|
|
bnEnd (&ry);
|
|
bnEnd (&k);
|
|
bnEnd (&kinv);
|
|
bnEnd (&s1);
|
|
bnEnd (&h);
|
|
bnEnd (&pkx);
|
|
bnEnd (&pky);
|
|
bnEnd (&P);
|
|
bnEnd (&Gx);
|
|
bnEnd (&Gy);
|
|
bnEnd (&n);
|
|
|
|
s = zrtp_status_ok;
|
|
} while (0);
|
|
|
|
return s;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
/* Verify a signature value - hash must be size matching the curve */
|
|
/* Signing key should be in peer_pv entry of dsa_cc */
|
|
/*----------------------------------------------------------------------------*/
|
|
static zrtp_status_t ECDSA_verify( struct zrtp_sig_scheme *self,
|
|
zrtp_dsa_crypto_context_t *dsa_cc,
|
|
zrtp_ec_params_t *ec_params,
|
|
uint8_t *hash, uint32_t hash_len,
|
|
struct BigNum *dsasig )
|
|
{
|
|
zrtp_status_t s = zrtp_status_fail;
|
|
struct BigNum P, Gx, Gy, n;
|
|
struct BigNum rx, ry, pkx, pky, r, s1, sinv, u1, u2, u1x, u2x, u1y, u2y, h;
|
|
unsigned ec_bytes;
|
|
|
|
if (!ec_params)
|
|
return zrtp_status_bad_param;
|
|
|
|
ec_bytes = (ec_params->ec_bits+7) / 8;
|
|
|
|
do
|
|
{
|
|
if (!self || !dsa_cc)
|
|
{
|
|
s = zrtp_status_bad_param;
|
|
break;
|
|
}
|
|
|
|
bnBegin(&P);
|
|
bnInsertBigBytes( &P, ec_params->P_data, 0, ec_bytes );
|
|
bnBegin(&Gx);
|
|
bnInsertBigBytes( &Gx, ec_params->Gx_data, 0, ec_bytes );
|
|
bnBegin(&Gy);
|
|
bnInsertBigBytes( &Gy, ec_params->Gy_data, 0, ec_bytes );
|
|
bnBegin(&n);
|
|
bnInsertBigBytes( &n, ec_params->n_data, 0, ec_bytes );
|
|
|
|
/* hash */
|
|
bnBegin(&h);
|
|
bnInsertBigBytes( &h, hash, 0, hash_len );
|
|
bnMod (&h, &h, &P);
|
|
|
|
/* Unpack sig */
|
|
bnBegin(&r);
|
|
bnBegin(&s1);
|
|
bnSetQ (&r, 1);
|
|
bnLShift (&r, ec_bytes*8);
|
|
bnMod (&s1, dsasig, &r);
|
|
bnCopy (&r, dsasig);
|
|
bnRShift (&r, ec_bytes*8);
|
|
|
|
/* Unpack signing key */
|
|
bnBegin(&pkx);
|
|
bnBegin(&pky);
|
|
bnSetQ (&pkx, 1);
|
|
bnLShift (&pkx, ec_bytes*8);
|
|
bnMod (&pky, &dsa_cc->peer_pv, &pkx);
|
|
bnCopy (&pkx, &dsa_cc->peer_pv);
|
|
bnRShift (&pkx, ec_bytes*8);
|
|
|
|
/* Verify signature */
|
|
bnBegin (&sinv);
|
|
bnInv (&sinv, &s1, &n);
|
|
bnBegin (&u1);
|
|
bnBegin (&u2);
|
|
bnMulMod_ (&u1, &sinv, &h, &n);
|
|
bnMulMod_ (&u2, &sinv, &r, &n);
|
|
|
|
bnBegin (&u1x);
|
|
bnBegin (&u1y);
|
|
bnBegin (&u2x);
|
|
bnBegin (&u2y);
|
|
bnBegin (&rx);
|
|
bnBegin (&ry);
|
|
zrtp_ecMul (&u1x, &u1y, &u1, &Gx, &Gy, &P);
|
|
zrtp_ecMul (&u2x, &u2y, &u2, &pkx, &pky, &P);
|
|
zrtp_ecAdd (&rx, &ry, &u1x, &u1y, &u2x, &u2y, &P);
|
|
|
|
if (bnCmp (&rx, &r) == 0) {
|
|
s = zrtp_status_ok;
|
|
} else {
|
|
s = zrtp_status_fail;
|
|
}
|
|
|
|
/* Clean up */
|
|
bnEnd (&rx);
|
|
bnEnd (&ry);
|
|
bnEnd (&r);
|
|
bnEnd (&s1);
|
|
bnEnd (&sinv);
|
|
bnEnd (&u1);
|
|
bnEnd (&u1x);
|
|
bnEnd (&u1y);
|
|
bnEnd (&u2);
|
|
bnEnd (&u2x);
|
|
bnEnd (&u2y);
|
|
bnEnd (&h);
|
|
bnEnd (&pkx);
|
|
bnEnd (&pky);
|
|
bnEnd (&P);
|
|
bnEnd (&Gx);
|
|
bnEnd (&Gy);
|
|
bnEnd (&n);
|
|
|
|
} while (0);
|
|
|
|
return s;
|
|
}
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
static zrtp_status_t EC_dummy(void *s)
|
|
{
|
|
return zrtp_status_ok;
|
|
}
|
|
|
|
|
|
/*============================================================================*/
|
|
/* P-256 (FIPS 186-3) support. See RFC 4753, section 3.1. */
|
|
/*============================================================================*/
|
|
|
|
/* Test vectors from RFC4754 */
|
|
#ifdef ZRTP_TEST_VECTORS
|
|
static uint8_t sv256_data[] = {
|
|
0xDC, 0x51, 0xD3, 0x86, 0x6A, 0x15, 0xBA, 0xCD,
|
|
0xE3, 0x3D, 0x96, 0xF9, 0x92, 0xFC, 0xA9, 0x9D,
|
|
0xA7, 0xE6, 0xEF, 0x09, 0x34, 0xE7, 0x09, 0x75,
|
|
0x59, 0xC2, 0x7F, 0x16, 0x14, 0xC8, 0x8A, 0x7F,
|
|
};
|
|
static uint8_t pvx256_data[] = {
|
|
0x24, 0x42, 0xA5, 0xCC, 0x0E, 0xCD, 0x01, 0x5F,
|
|
0xA3, 0xCA, 0x31, 0xDC, 0x8E, 0x2B, 0xBC, 0x70,
|
|
0xBF, 0x42, 0xD6, 0x0C, 0xBC, 0xA2, 0x00, 0x85,
|
|
0xE0, 0x82, 0x2C, 0xB0, 0x42, 0x35, 0xE9, 0x70,
|
|
};
|
|
static uint8_t pvy256_data[] = {
|
|
0x6F, 0xC9, 0x8B, 0xD7, 0xE5, 0x02, 0x11, 0xA4,
|
|
0xA2, 0x71, 0x02, 0xFA, 0x35, 0x49, 0xDF, 0x79,
|
|
0xEB, 0xCB, 0x4B, 0xF2, 0x46, 0xB8, 0x09, 0x45,
|
|
0xCD, 0xDF, 0xE7, 0xD5, 0x09, 0xBB, 0xFD, 0x7D,
|
|
};
|
|
|
|
static uint8_t k256_data[] = {
|
|
0x9E, 0x56, 0xF5, 0x09, 0x19, 0x67, 0x84, 0xD9,
|
|
0x63, 0xD1, 0xC0, 0xA4, 0x01, 0x51, 0x0E, 0xE7,
|
|
0xAD, 0xA3, 0xDC, 0xC5, 0xDE, 0xE0, 0x4B, 0x15,
|
|
0x4B, 0xF6, 0x1A, 0xF1, 0xD5, 0xA6, 0xDE, 0xCE,
|
|
};
|
|
static uint8_t rx256_data[] = {
|
|
0xCB, 0x28, 0xE0, 0x99, 0x9B, 0x9C, 0x77, 0x15,
|
|
0xFD, 0x0A, 0x80, 0xD8, 0xE4, 0x7A, 0x77, 0x07,
|
|
0x97, 0x16, 0xCB, 0xBF, 0x91, 0x7D, 0xD7, 0x2E,
|
|
0x97, 0x56, 0x6E, 0xA1, 0xC0, 0x66, 0x95, 0x7C,
|
|
};
|
|
static uint8_t ry256_data[] = {
|
|
0x2B, 0x57, 0xC0, 0x23, 0x5F, 0xB7, 0x48, 0x97,
|
|
0x68, 0xD0, 0x58, 0xFF, 0x49, 0x11, 0xC2, 0x0F,
|
|
0xDB, 0xE7, 0x1E, 0x36, 0x99, 0xD9, 0x13, 0x39,
|
|
0xAF, 0xBB, 0x90, 0x3E, 0xE1, 0x72, 0x55, 0xDC,
|
|
};
|
|
|
|
static uint8_t h256_data[] = {
|
|
0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
|
|
0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
|
|
0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
|
|
0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD,
|
|
};
|
|
static uint8_t s256_data[] = {
|
|
0x86, 0xFA, 0x3B, 0xB4, 0xE2, 0x6C, 0xAD, 0x5B,
|
|
0xF9, 0x0B, 0x7F, 0x81, 0x89, 0x92, 0x56, 0xCE,
|
|
0x75, 0x94, 0xBB, 0x1E, 0xA0, 0xC8, 0x92, 0x12,
|
|
0x74, 0x8B, 0xFF, 0x3B, 0x3D, 0x5B, 0x03, 0x15,
|
|
};
|
|
|
|
|
|
#endif
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
/* Return dsa_cc->pv holding public value and dsa_cc->sv holding secret value */
|
|
/* The public value is an elliptic curve point encoded as the x part shifted */
|
|
/* left 256 bits and or'd with the y part. */
|
|
/*----------------------------------------------------------------------------*/
|
|
static zrtp_status_t EC256P_keygen( struct zrtp_sig_scheme *self,
|
|
zrtp_dsa_crypto_context_t *dsa_cc )
|
|
{
|
|
struct zrtp_ec_params params;
|
|
zrtp_ec_init_params(¶ms, 256);
|
|
return ECDSA_keygen(self, dsa_cc, ¶ms,
|
|
#ifdef ZRTP_TEST_VECTORS
|
|
sv256_data, sizeof(sv256_data),
|
|
pvx256_data, sizeof(pvx256_data),
|
|
pvy256_data, sizeof(pvy256_data),
|
|
#endif
|
|
256);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
/* Sign the specified hash value */
|
|
/*----------------------------------------------------------------------------*/
|
|
static zrtp_status_t EC256P_sign( struct zrtp_sig_scheme *self,
|
|
zrtp_dsa_crypto_context_t *dsa_cc,
|
|
uint8_t *hash, uint32_t hash_len,
|
|
struct BigNum *dsasig )
|
|
{
|
|
struct zrtp_ec_params params;
|
|
zrtp_ec_init_params(¶ms, 256);
|
|
return ECDSA_sign(self, dsa_cc, ¶ms,
|
|
#ifdef ZRTP_TEST_VECTORS
|
|
k256_data, sizeof(k256_data),
|
|
rx256_data, sizeof(rx256_data),
|
|
ry256_data, sizeof(ry256_data),
|
|
s256_data, sizeof(s256_data),
|
|
h256_data, sizeof(h256_data),
|
|
#else
|
|
hash, hash_len,
|
|
#endif
|
|
dsasig);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
/* Verify the signature on the hash value */
|
|
/*----------------------------------------------------------------------------*/
|
|
static zrtp_status_t EC256P_verify(struct zrtp_sig_scheme *self,
|
|
zrtp_dsa_crypto_context_t *dsa_cc,
|
|
uint8_t *hash, uint32_t hash_len,
|
|
struct BigNum *dsasig )
|
|
{
|
|
struct zrtp_ec_params params;
|
|
zrtp_ec_init_params(¶ms, 256);
|
|
return ECDSA_verify(self, dsa_cc, ¶ms,
|
|
#ifdef ZRTP_TEST_VECTORS
|
|
h256_data, sizeof(h256_data),
|
|
#else
|
|
hash, hash_len,
|
|
#endif
|
|
dsasig);
|
|
}
|
|
|
|
|
|
|
|
/*============================================================================*/
|
|
/* P-384 (FIPS 186-3) support. See RFC 4753, section 3.2. */
|
|
/*============================================================================*/
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
/* Return dsa_cc->pv holding public value and dsa_cc->sv holding secret value */
|
|
/* The public value is an elliptic curve point encoded as the x part shifted */
|
|
/* left 384 bits and or'd with the y part. */
|
|
/*----------------------------------------------------------------------------*/
|
|
static zrtp_status_t EC384P_keygen( struct zrtp_sig_scheme *self,
|
|
zrtp_dsa_crypto_context_t *dsa_cc )
|
|
{
|
|
struct zrtp_ec_params params;
|
|
zrtp_ec_init_params(¶ms, 384);
|
|
return ECDSA_keygen(self, dsa_cc, ¶ms,
|
|
#ifdef ZRTP_TEST_VECTORS
|
|
0, 0, 0, 0, 0, 0,
|
|
#endif
|
|
384);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
/* Sign the specified hash value */
|
|
/*----------------------------------------------------------------------------*/
|
|
static zrtp_status_t EC384P_sign( struct zrtp_sig_scheme *self,
|
|
zrtp_dsa_crypto_context_t *dsa_cc,
|
|
uint8_t *hash, uint32_t hash_len,
|
|
struct BigNum *dsasig )
|
|
{
|
|
struct zrtp_ec_params params;
|
|
zrtp_ec_init_params(¶ms, 384);
|
|
return ECDSA_sign(self, dsa_cc, ¶ms,
|
|
#ifdef ZRTP_TEST_VECTORS
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
#endif
|
|
hash, hash_len, dsasig);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
/* Verify the signature on the hash value */
|
|
/*----------------------------------------------------------------------------*/
|
|
static zrtp_status_t EC384P_verify(struct zrtp_sig_scheme *self,
|
|
zrtp_dsa_crypto_context_t *dsa_cc,
|
|
uint8_t *hash, uint32_t hash_len,
|
|
struct BigNum *dsasig )
|
|
{
|
|
struct zrtp_ec_params params;
|
|
zrtp_ec_init_params(¶ms, 384);
|
|
return ECDSA_verify(self, dsa_cc, ¶ms, hash, hash_len, dsasig);
|
|
}
|
|
|
|
|
|
|
|
/*============================================================================*/
|
|
/* P-521 (FIPS 186-3) support. See RFC 4753, section 3.3. */
|
|
/*============================================================================*/
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
/* Return dsa_cc->pv holding public value and dsa_cc->sv holding secret value */
|
|
/* The public value is an elliptic curve point encoded as the x part shifted */
|
|
/* left 528 bits (note, not 521) and or'd with the y part. */
|
|
/*----------------------------------------------------------------------------*/
|
|
static zrtp_status_t EC521P_keygen( struct zrtp_sig_scheme *self,
|
|
zrtp_dsa_crypto_context_t *dsa_cc )
|
|
{
|
|
struct zrtp_ec_params params;
|
|
zrtp_ec_init_params(¶ms, 521);
|
|
return ECDSA_keygen(self, dsa_cc, ¶ms,
|
|
#ifdef ZRTP_TEST_VECTORS
|
|
0, 0, 0, 0, 0, 0,
|
|
#endif
|
|
528);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
/* Sign the specified hash value */
|
|
/*----------------------------------------------------------------------------*/
|
|
static zrtp_status_t EC521P_sign( struct zrtp_sig_scheme *self,
|
|
zrtp_dsa_crypto_context_t *dsa_cc,
|
|
uint8_t *hash, uint32_t hash_len,
|
|
struct BigNum *dsasig )
|
|
{
|
|
struct zrtp_ec_params params;
|
|
zrtp_ec_init_params(¶ms, 521);
|
|
return ECDSA_sign(self, dsa_cc, ¶ms,
|
|
#ifdef ZRTP_TEST_VECTORS
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
#endif
|
|
hash, hash_len, dsasig);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
/* Verify the signature on the hash value */
|
|
/*----------------------------------------------------------------------------*/
|
|
static zrtp_status_t EC521P_verify(struct zrtp_sig_scheme *self,
|
|
zrtp_dsa_crypto_context_t *dsa_cc,
|
|
uint8_t *hash, uint32_t hash_len,
|
|
struct BigNum *dsasig )
|
|
{
|
|
struct zrtp_ec_params params;
|
|
zrtp_ec_init_params(¶ms, 521);
|
|
return ECDSA_verify(self, dsa_cc, ¶ms, hash, hash_len, dsasig);
|
|
}
|
|
|
|
|
|
|
|
/*============================================================================*/
|
|
/* Public Key support */
|
|
/*============================================================================*/
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
zrtp_status_t zrtp_defaults_sig(zrtp_global_ctx_t* zrtp_global)
|
|
{
|
|
zrtp_sig_scheme_t* ec256p = zrtp_sys_alloc(sizeof(zrtp_sig_scheme_t));
|
|
zrtp_sig_scheme_t* ec384p = zrtp_sys_alloc(sizeof(zrtp_sig_scheme_t));
|
|
zrtp_sig_scheme_t* ec521p = zrtp_sys_alloc(sizeof(zrtp_sig_scheme_t));
|
|
|
|
if (!ec256p || !ec384p || !ec521p)
|
|
{
|
|
if(ec256p) zrtp_sys_free(ec256p);
|
|
if(ec384p) zrtp_sys_free(ec384p);
|
|
if(ec521p) zrtp_sys_free(ec521p);
|
|
return zrtp_status_alloc_fail;
|
|
}
|
|
|
|
zrtp_memset(ec256p, 0, sizeof(zrtp_sig_scheme_t));
|
|
zrtp_memcpy(ec256p->base.type, ZRTP_EC256P, ZRTP_COMP_TYPE_SIZE);
|
|
ec256p->base.id = ZRTP_SIGTYPE_EC256P;
|
|
ec256p->base.zrtp_global = zrtp_global;
|
|
ec256p->sv_length = 256/8;
|
|
ec256p->pv_length = 2*256/8;
|
|
ec256p->base.init = EC_dummy;
|
|
ec256p->base.free = EC_dummy;
|
|
ec256p->generate_key = EC256P_keygen;
|
|
ec256p->sign = EC256P_sign;
|
|
ec256p->verify = EC256P_verify;
|
|
|
|
zrtp_memset(ec384p, 0, sizeof(zrtp_sig_scheme_t));
|
|
zrtp_memcpy(ec384p->base.type, ZRTP_EC384P, ZRTP_COMP_TYPE_SIZE);
|
|
ec384p->base.id = ZRTP_SIGTYPE_EC384P;
|
|
ec384p->base.zrtp_global = zrtp_global;
|
|
ec384p->sv_length = 384/8;
|
|
ec384p->pv_length = 2*384/8;
|
|
ec384p->base.init = EC_dummy;
|
|
ec384p->base.free = EC_dummy;
|
|
ec384p->generate_key = EC384P_keygen;
|
|
ec384p->sign = EC384P_sign;
|
|
ec384p->verify = EC384P_verify;
|
|
|
|
zrtp_memset(ec521p, 0, sizeof(zrtp_sig_scheme_t));
|
|
zrtp_memcpy(ec521p->base.type, ZRTP_EC521P, ZRTP_COMP_TYPE_SIZE);
|
|
ec521p->base.id = ZRTP_SIGTYPE_EC521P;
|
|
ec521p->base.zrtp_global = zrtp_global;
|
|
ec521p->sv_length = 528/8;
|
|
ec521p->pv_length = 2*528/8;
|
|
ec521p->base.init = EC_dummy;
|
|
ec521p->base.free = EC_dummy;
|
|
ec521p->generate_key = EC521P_keygen;
|
|
ec521p->sign = EC521P_sign;
|
|
ec521p->verify = EC521P_verify;
|
|
|
|
zrtp_register_comp(ZRTP_CC_SIG, ec256p, zrtp_global);
|
|
zrtp_register_comp(ZRTP_CC_SIG, ec384p, zrtp_global);
|
|
zrtp_register_comp(ZRTP_CC_SIG, ec521p, zrtp_global);
|
|
|
|
return zrtp_status_ok;
|
|
}
|
|
|
|
#endif /* don't have disgital signature ready for the moment*/
|