Add back the elliptic curve (ECC) files

Signed-off-by: Travis Cross <tc@traviscross.com>
Signed-off-by: Philip Zimmermann <prz@mit.edu>
This commit is contained in:
Travis Cross 2013-02-10 21:54:15 +00:00
parent fafd8f337c
commit 8843819ce5
9 changed files with 1828 additions and 15 deletions

View File

@ -123,7 +123,7 @@
#endif
#ifndef ZRTP_ENABLE_EC
#define ZRTP_ENABLE_EC 0
#define ZRTP_ENABLE_EC 1
#endif
#ifndef ZRTP_DEBUG_WITH_PJSIP

View File

@ -0,0 +1,89 @@
/*
* zrtp_crypto_ec.c - Elliptic Curve Low Level Crypto functions for ZRTP.
* NSA Suite B Elliptic Curves from NIST SP 800-56A and FIPS 186-3.
*
* Copyright (c) 2006-2009 Philip R. Zimmermann. All rights reserved.
* This is NOT licensed under the GPL or any other open source license.
* For licensing terms or other information,
* contact: Philip Zimmermann <prz@mit.edu>.
* For more contact information, see http://philzimmermann.com
*/
#ifndef __ZRTP_CRYPTO_EC_H__
#define __ZRTP_CRYPTO_EC_H__
#include "bn.h"
#include "zrtp_config.h"
#include "zrtp_types.h"
#include "zrtp_error.h"
#if (defined(ZRTP_ENABLE_EC) && (ZRTP_ENABLE_EC == 1))
#define ZRTP_MAXECBITS 521
#define ZRTP_MAXECWORDS ((ZRTP_MAXECBITS+7)/8)
typedef struct zrtp_ec_params
{
unsigned ec_bits; /* # EC bits: 256, 384, 521 */
uint8_t P_data[ZRTP_MAXECWORDS]; /* curve field prime */
uint8_t n_data[ZRTP_MAXECWORDS]; /* curve order (# points) */
uint8_t b_data[ZRTP_MAXECWORDS]; /* curve param, y^3 = x^2 -3x + b */
uint8_t Gx_data[ZRTP_MAXECWORDS]; /* curve point, x coordinate */
uint8_t Gy_data[ZRTP_MAXECWORDS]; /* curve point, y coordinate */
} zrtp_ec_params_t;
#if defined(__cplusplus)
extern "C"
{
#endif
/*============================================================================*/
/* Elliptic Curve library */
/*============================================================================*/
int zrtp_ecAdd ( struct BigNum *rsltx,
struct BigNum *rslty,
struct BigNum *p1x,
struct BigNum *p1y,
struct BigNum *p2x,
struct BigNum *p2y,
struct BigNum *mod);
int zrtp_ecMul ( struct BigNum *rsltx,
struct BigNum *rslty,
struct BigNum *mult,
struct BigNum *basex,
struct BigNum *basey,
struct BigNum *mod);
zrtp_status_t zrtp_ec_random_point( zrtp_global_t *zrtp,
struct BigNum *P,
struct BigNum *n,
struct BigNum *Gx,
struct BigNum *Gy,
struct BigNum *pkx,
struct BigNum *pky,
struct BigNum *sv,
uint8_t *test_sv_data,
size_t test_sv_data_len);
extern zrtp_status_t zrtp_ec_init_params(struct zrtp_ec_params *params, uint32_t bits );
/* Useful bignum utility functions not defined in bignum library */
int bnAddMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod);
int bnAddQMod_ (struct BigNum *rslt, unsigned n1, struct BigNum *mod);
int bnSubMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod);
int bnSubQMod_ (struct BigNum *rslt, unsigned n1, struct BigNum *mod);
int bnMulMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *n2, struct BigNum *mod);
int bnMulQMod_ (struct BigNum *rslt, struct BigNum *n1, unsigned n2, struct BigNum *mod);
int bnSquareMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod);
#if defined(__cplusplus)
}
#endif
#endif /*ZRTP_ENABLE_EC*/
#endif /* __ZRTP_CRYPTO_EC_H__ */

View File

@ -43,7 +43,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../include;../../third_party/bnlib;../../third_party/bgaes;../../test/include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H=1;ZRTP_ENABLE_EC=0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H=1;ZRTP_ENABLE_EC=1"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@ -109,7 +109,7 @@
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../include;../../third_party/bnlib;../../third_party/bgaes"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H=1;ZRTP_ENABLE_EC=0"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H=1;ZRTP_ENABLE_EC=1"
ExceptionHandling="0"
RuntimeLibrary="0"
StructMemberAlignment="0"
@ -180,6 +180,10 @@
RelativePath="..\..\include\zrtp_crypto.h"
>
</File>
<File
RelativePath="..\..\include\zrtp_ec.h"
>
</File>
<File
RelativePath="..\..\include\zrtp_engine.h"
>
@ -244,6 +248,10 @@
RelativePath="..\..\include\zrtp_utils.h"
>
</File>
<File
RelativePath="..\..\include\zrtp_version.h"
>
</File>
</Filter>
<Filter
Name="src"
@ -264,6 +272,14 @@
RelativePath="..\..\src\zrtp_crypto_atl.c"
>
</File>
<File
RelativePath="..\..\src\zrtp_crypto_ec.c"
>
</File>
<File
RelativePath="..\..\src\zrtp_crypto_ecdh.c"
>
</File>
<File
RelativePath="..\..\src\zrtp_crypto_hash.c"
>

View File

@ -52,7 +52,7 @@
ExecutionBucket="7"
Optimization="0"
AdditionalIncludeDirectories="../../third_party/bnlib;../../include;../../include/enterprise;../../third_party/bgaes;../../test/include"
PreprocessorDefinitions="_DEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;DEBUG;_LIB;$(ARCHFAM);$(_ARCHFAM_);_UNICODE;UNICODE;ZRTP_ENABLE_EC=0"
PreprocessorDefinitions="_DEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;DEBUG;_LIB;$(ARCHFAM);$(_ARCHFAM_);_UNICODE;UNICODE;ZRTP_ENABLE_EC=1"
MinimalRebuild="true"
RuntimeLibrary="1"
StructMemberAlignment="0"
@ -136,7 +136,7 @@
ExecutionBucket="7"
Optimization="0"
AdditionalIncludeDirectories="../../third_party/bnlib;../../include;../../include/enterprise;../../third_party/bgaes;../../test/include"
PreprocessorDefinitions="_DEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;DEBUG;_LIB;$(ARCHFAM);$(_ARCHFAM_);_UNICODE;ZRTP_ENABLE_EC=0"
PreprocessorDefinitions="_DEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;DEBUG;_LIB;$(ARCHFAM);$(_ARCHFAM_);_UNICODE;ZRTP_ENABLE_EC=1"
MinimalRebuild="true"
RuntimeLibrary="1"
BufferSecurityCheck="false"
@ -219,7 +219,7 @@
ExecutionBucket="7"
Optimization="2"
AdditionalIncludeDirectories="../../third_party/bnlib;../../include;../../include/enterprise;../../third_party/bgaes;../../test/include"
PreprocessorDefinitions="NDEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;_LIB;$(ARCHFAM);$(_ARCHFAM_);_UNICODE;ZRTP_ENABLE_EC=0"
PreprocessorDefinitions="NDEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;_LIB;$(ARCHFAM);$(_ARCHFAM_);_UNICODE;ZRTP_ENABLE_EC=1"
RuntimeLibrary="0"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
@ -300,7 +300,7 @@
ExecutionBucket="7"
Optimization="2"
AdditionalIncludeDirectories="../../third_party/bnlib;../../include;../../include/enterprise;../../third_party/bgaes;../../test/include"
PreprocessorDefinitions="NDEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;_LIB;$(ARCHFAM);$(_ARCHFAM_);_UNICODE;UNICODE;ZRTP_ENABLE_EC=0"
PreprocessorDefinitions="NDEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;_LIB;$(ARCHFAM);$(_ARCHFAM_);_UNICODE;UNICODE;ZRTP_ENABLE_EC=1"
RuntimeLibrary="0"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
@ -382,6 +382,10 @@
RelativePath="..\..\include\zrtp_crypto.h"
>
</File>
<File
RelativePath="..\..\include\zrtp_ec.h"
>
</File>
<File
RelativePath="..\..\include\zrtp_engine.h"
>
@ -462,6 +466,18 @@
RelativePath="..\..\src\zrtp_crypto_atl.c"
>
</File>
<File
RelativePath="..\..\src\zrtp_crypto_ec.c"
>
</File>
<File
RelativePath="..\..\src\zrtp_crypto_ecdh.c"
>
</File>
<File
RelativePath="..\..\src\zrtp_crypto_ecdsa.c"
>
</File>
<File
RelativePath="..\..\src\zrtp_crypto_hash.c"
>
@ -482,6 +498,10 @@
RelativePath="..\..\src\zrtp_engine.c"
>
</File>
<File
RelativePath="..\..\src\zrtp_engine_driven.c"
>
</File>
<File
RelativePath="..\..\src\zrtp_iface_cache.c"
>

View File

@ -43,6 +43,9 @@ protocol = \
../../src/zrtp_crypto_sas.obj \
../../src/zrtp_datatypes.obj \
../../src/zrtp_engine.obj \
../../src/enterprise/zrtp_engine_driven.obj \
../../src/enterprise/zrtp_crypto_ec.obj \
../../src/enterprise/zrtp_crypto_ecdh.obj \
../../src/zrtp_iface_sys.obj \
../../src/zrtp_initiator.obj \
../../src/zrtp_legal.obj \
@ -71,13 +74,13 @@ OBJECTS = $(bnlib) $(protocol) $(bgaes)
# Debug
OUT_DIR = debug.km
OUT_DIR = debug_ec.km
DEFINES_D = -D_X86_=1 -Di386=1 -DSTD_CALL -DCONDITION_HANDLING=1 \
-DNT_UP=1 -DNT_INST=0 -DWIN32=100 -D_NT1X_=100 \
-DWINNT=1 -D_WIN32_WINNT=0x0500 -DWIN32_LEAN_AND_MEAN=1 -DDBG=1 -D_DEBUG -DDEBUG -DDEVL=1 \
-DFPO=0 -D_DLL=1 -D_IDWBUILD -DRDRDBG -DSRVDBG -DDBG_MESSAGES=1 \
-D_UNICODE -DLITTLE_ENDIAN -DZRTP_USE_ENTERPRISE=0
-D_UNICODE -DLITTLE_ENDIAN -DZRTP_USE_ENTERPRISE=1
CFLAGS_D = $(DEFINES_D) -Zel -Zp8 -Gy -cbstring -Gz -QIfdiv- -QIf -Gi- -Gm- -GX- \
-GR- -GF -FI$(DDK)\inc\$(OS)\warning.h -Z7 -Od -Oi -Oy- -W3
@ -86,13 +89,13 @@ CFLAGS_D = $(DEFINES_D) -Zel -Zp8 -Gy -cbstring -Gz -QIfdiv- -QIf -Gi- -Gm- -GX-
# Release
OUT_DIR = release.km
OUT_DIR = release_ec.km
DEFINES_D = -D_X86_=1 -Di386=1 -DSTD_CALL -DCONDITION_HANDLING=1 \
-DNT_UP=1 -DNO_DISK_ACCESS -DNT_INST=0 -DWIN32=100 -D_NT1X_=100 \
-DWINNT=1 -D_WIN32_WINNT=0x0500 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 \
-DFPO=1 -DNDEBUG -D_DLL=1 -D_IDWBUILD -D_UNICODE \
-DLITTLE_ENDIAN -DZRTP_USE_ENTERPRISE=0
-DLITTLE_ENDIAN -DZRTP_USE_ENTERPRISE=1
CFLAGS_D = $(DEFINES_D) -Zel -Zp8 -Gy -cbstring -Gz -QIfdiv- -QIf -Gi- -Gm- -GX- \
-GR- -GF -Oxs -Oy -FI$(DDK)\inc\$(OS)\warning.h -W3 -FAcs -Z7

View File

@ -44,6 +44,9 @@ protocol = \
../../src/zrtp_crypto_sas.obj \
../../src/zrtp_datatypes.obj \
../../src/zrtp_engine.obj \
../../src/enterprise/zrtp_engine_driven.obj \
../../src/enterprise/zrtp_crypto_ec.obj \
../../src/enterprise/zrtp_crypto_ecdh.obj \
../../src/zrtp_iface_sys.obj \
../../src/zrtp_initiator.obj \
../../src/zrtp_legal.obj \
@ -72,14 +75,14 @@ OBJECTS = $(bnlib) $(protocol) $(bgaes)
# Debug
OUT_DIR = debug64.km
OUT_DIR = debug64_ec.km
DEFINES_D = -DWIN64=1 -D_WIN64=1 -D_AMD64_=1 -D_M_AMD64 -D_WINDOWS \
-DSTD_CALL -DCONDITION_HANDLING=1 \
-DNT_UP=1 -DNT_INST=0 -D_NT1X_=100 \
-DWINNT=1 -D_WIN32_WINNT=0x0500 -DWIN32_LEAN_AND_MEAN=1 -DDBG=1 -D_DEBUG -DDEBUG -DDEVL=1 \
-DFPO=0 -D_DLL=1 -D_IDWBUILD -DRDRDBG -DSRVDBG -DDBG_MESSAGES=1 \
-D_UNICODE -DLITTLE_ENDIAN -DZRTP_USE_ENTERPRISE=0
-D_UNICODE -DLITTLE_ENDIAN -DZRTP_USE_ENTERPRISE=1
CFLAGS_D = $(DEFINES_D) -Zp8 -Gy -cbstring -Gz -Gm- -EHs-c- \
-GR- -GF -FI$(DDK)\inc\$(OS)\warning.h -Z7 -Od -Oi -Oy- -W3
@ -88,14 +91,14 @@ CFLAGS_D = $(DEFINES_D) -Zp8 -Gy -cbstring -Gz -Gm- -EHs-c- \
# Release
OUT_DIR = release64.km
OUT_DIR = release64_ec.km
DEFINES_D = -DWIN64=1 -D_WIN64=1 -D_AMD64_=1 -D_M_AMD64 -D_WINDOWS \
-DSTD_CALL -DCONDITION_HANDLING=1 \
-DNT_UP=1 -DNO_DISK_ACCESS -DNT_INST=0 -DWIN32=100 -D_NT1X_=100 \
-DWINNT=1 -D_WIN32_WINNT=0x0500 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 \
-DFPO=1 -DNDEBUG -D_DLL=1 -D_IDWBUILD -D_UNICODE \
-DLITTLE_ENDIAN -DZRTP_USE_ENTERPRISE=0
-DLITTLE_ENDIAN -DZRTP_USE_ENTERPRISE=1
CFLAGS_D = $(DEFINES_D) -Zel -Zp8 -Gy -cbstring -Gz -QIfdiv- -QIf -Gi- -Gm- -GX- \
-GR- -GF -Oxs -Oy -FI$(DDK)\inc\$(OS)\warning.h -W3 -FAcs -Z7

View File

@ -0,0 +1,469 @@
/*
* zrtp_crypto_ec.c - Elliptic Curve Low Level Crypto functions for ZRTP.
* NSA Suite B Elliptic Curves from NIST SP 800-56A and FIPS 186-3.
*
* Copyright (c) 2006-2009 Philip R. Zimmermann. All rights reserved.
* This is NOT licensed under the GPL or any other open source license.
* For licensing terms or other information,
* contact: Philip Zimmermann <prz@mit.edu>.
* For more contact information, see http://philzimmermann.com
*/
#include "zrtp.h"
#if (defined(ZRTP_ENABLE_EC) && (ZRTP_ENABLE_EC == 1))
/* Size of extra random data to approximate a uniform distribution mod n */
#define UNIFORMBYTES 8
/*============================================================================*/
/* Bignum Shorthand Functions */
/*============================================================================*/
int bnAddMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod)
{
bnAdd (rslt, n1);
if (bnCmp (rslt, mod) >= 0) {
bnSub (rslt, mod);
}
return 0;
}
int bnAddQMod_ (struct BigNum *rslt, unsigned n1, struct BigNum *mod)
{
bnAddQ (rslt, n1);
if (bnCmp (rslt, mod) >= 0) {
bnSub (rslt, mod);
}
return 0;
}
int bnSubMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod)
{
if (bnCmp (rslt, n1) < 0) {
bnAdd (rslt, mod);
}
bnSub (rslt, n1);
return 0;
}
int bnSubQMod_ (struct BigNum *rslt, unsigned n1, struct BigNum *mod)
{
if (bnCmpQ (rslt, n1) < 0) {
bnAdd (rslt, mod);
}
bnSubQ (rslt, n1);
return 0;
}
int bnMulMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *n2, struct BigNum *mod)
{
bnMul (rslt, n1, n2);
bnMod (rslt, rslt, mod);
return 0;
}
int bnMulQMod_ (struct BigNum *rslt, struct BigNum *n1, unsigned n2, struct BigNum *mod)
{
bnMulQ (rslt, n1, n2);
bnMod (rslt, rslt, mod);
return 0;
}
int bnSquareMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod)
{
bnSquare (rslt, n1);
bnMod (rslt, rslt, mod);
return 0;
}
/*============================================================================*/
/* Elliptic Curve arithmetic */
/*============================================================================*/
/* Add two elliptic curve points. Any of them may be the same object. */
int zrtp_ecAdd ( struct BigNum *rsltx, struct BigNum *rslty,
struct BigNum *p1x, struct BigNum *p1y,
struct BigNum *p2x, struct BigNum *p2y, struct BigNum *mod)
{
struct BigNum trsltx, trslty;
struct BigNum t1, gam;
struct BigNum bnzero;
bnBegin (&bnzero);
/* Check for an operand being zero */
if (bnCmp (p1x, &bnzero) == 0 && bnCmp (p1y, &bnzero) == 0) {
bnCopy (rsltx, p2x); bnCopy (rslty, p2y);
bnEnd (&bnzero);
return 0;
}
if (bnCmp (p2x, &bnzero) == 0 && bnCmp (p2y, &bnzero) == 0) {
bnCopy (rsltx, p1x); bnCopy (rslty, p1y);
bnEnd (&bnzero);
return 0;
}
/* Check if p1 == -p2 and return 0 if so */
if (bnCmp (p1x, p2x) == 0) {
struct BigNum tsum;
bnBegin (&tsum);
bnCopy (&tsum, p1x);
bnAddMod_ (&tsum, p2x, mod);
if (bnCmp (&tsum, &bnzero) == 0) {
bnSetQ (rsltx, 0); bnSetQ (rslty, 0);
bnEnd (&tsum);
bnEnd (&bnzero);
return 0;
}
bnEnd (&tsum);
}
bnBegin (&t1);
bnBegin (&gam);
bnBegin (&trsltx);
bnBegin (&trslty);
/* Check for doubling, different formula for gamma */
if (bnCmp (p1x, p2x) == 0 && bnCmp (p1y, p2y) == 0) {
bnCopy (&t1, p1y);
bnAddMod_ (&t1, p1y, mod);
bnInv (&t1, &t1, mod);
bnSquareMod_ (&gam, p1x, mod);
bnMulQMod_ (&gam, &gam, 3, mod);
bnSubQMod_ (&gam, 3, mod);
bnMulMod_ (&gam, &gam, &t1, mod);
} else {
bnCopy (&t1, p2x);
bnSubMod_ (&t1, p1x, mod);
bnInv (&t1, &t1, mod);
bnCopy (&gam, p2y);
bnSubMod_ (&gam, p1y, mod);
bnMulMod_ (&gam, &gam, &t1, mod);
}
bnSquareMod_ (&trsltx, &gam, mod);
bnSubMod_ (&trsltx, p1x, mod);
bnSubMod_ (&trsltx, p2x, mod);
bnCopy (&trslty, p1x);
bnSubMod_ (&trslty, &trsltx, mod);
bnMulMod_ (&trslty, &trslty, &gam, mod);
bnSubMod_ (&trslty, p1y, mod);
bnCopy (rsltx, &trsltx);
bnCopy (rslty, &trslty);
bnEnd (&t1);
bnEnd (&gam);
bnEnd (&trsltx);
bnEnd (&trslty);
bnEnd (&bnzero);
return 0;
}
int zrtp_ecMul ( struct BigNum *rsltx, struct BigNum *rslty, struct BigNum *mult,
struct BigNum *basex, struct BigNum *basey, struct BigNum *mod)
{
struct BigNum bnzero;
struct BigNum tbasex, tbasey;
struct BigNum trsltx, trslty;
struct BigNum tmult;
bnBegin (&bnzero);
bnBegin (&tbasex);
bnBegin (&tbasey);
bnBegin (&trsltx);
bnBegin (&trslty);
bnBegin (&tmult);
/* Initialize result to 0 before additions */
bnSetQ (&trsltx, 0);
bnSetQ (&trslty, 0);
/* Make copies of base and multiplier */
bnCopy (&tbasex, basex);
bnCopy (&tbasey, basey);
bnCopy (&tmult, mult);
while (bnCmp (&tmult, &bnzero) > 0) {
/* Test lsb of mult */
unsigned lsw = bnLSWord (&tmult);
if (lsw & 1) {
/* Add base to result */
zrtp_ecAdd (&trsltx, &trslty, &trsltx, &trslty, &tbasex, &tbasey, mod);
}
/* Double the base */
zrtp_ecAdd (&tbasex, &tbasey, &tbasex, &tbasey, &tbasex, &tbasey, mod);
/* Shift multiplier right */
bnRShift (&tmult, 1);
}
bnCopy (rsltx, &trsltx);
bnCopy (rslty, &trslty);
bnEnd (&bnzero);
bnEnd (&tbasex);
bnEnd (&tbasey);
bnEnd (&trsltx);
bnEnd (&trslty);
bnEnd (&tmult);
return 0;
}
/*----------------------------------------------------------------------------*/
/* Choose a random point on the elliptic curve. */
/* Provision is made to use a given point from test vectors. */
/* pkx and pky are the output point, sv is output discrete log */
/* Input base is Gx, Gy; curve field modulus is P; curve order is n. */
/*----------------------------------------------------------------------------*/
zrtp_status_t zrtp_ec_random_point( zrtp_global_t *zrtp,
struct BigNum *P,
struct BigNum *n,
struct BigNum *Gx,
struct BigNum *Gy,
struct BigNum *pkx,
struct BigNum *pky,
struct BigNum *sv,
uint8_t *test_sv_data,
size_t test_sv_data_len)
{
zrtp_status_t s = zrtp_status_fail;
unsigned char* buffer = zrtp_sys_alloc(sizeof(zrtp_uchar1024_t));
if (!buffer) {
return zrtp_status_alloc_fail;
}
zrtp_memset(buffer, 0, sizeof(zrtp_uchar1024_t));
do
{
if (test_sv_data_len != 0) {
/* Force certain secret value */
if (bnBytes(P) != test_sv_data_len) {
break;
}
zrtp_memcpy(buffer+UNIFORMBYTES, test_sv_data, test_sv_data_len);
} else {
/* Choose random value, larger than needed so it will be uniform */
if (bnBytes(P)+UNIFORMBYTES != (uint32_t)zrtp_randstr(zrtp, buffer, bnBytes(P)+UNIFORMBYTES)) {
break; /* if we can't generate random string - fail initialization */
}
}
bnInsertBigBytes(sv, (const unsigned char *)buffer, 0, bnBytes(P)+UNIFORMBYTES);
bnMod(sv, sv, n);
zrtp_ecMul(pkx, pky, sv, Gx, Gy, P);
s = zrtp_status_ok;
} while (0);
if (buffer) {
zrtp_sys_free(buffer);
}
return s;
}
/*============================================================================*/
/* Curve parameters */
/*============================================================================*/
uint8_t P_256_data[] =
{
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
uint8_t n_256_data[] =
{
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51
};
uint8_t b_256_data[] =
{
0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7,
0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc,
0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 0xb0, 0xf6,
0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b
};
uint8_t Gx_256_data[] =
{
0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47,
0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2,
0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0,
0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96
};
uint8_t Gy_256_data[] =
{
0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b,
0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16,
0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5
};
uint8_t P_384_data[] =
{
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF
};
uint8_t n_384_data[] =
{
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF,
0x58, 0x1A, 0x0D, 0xB2, 0x48, 0xB0, 0xA7, 0x7A,
0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73
};
uint8_t b_384_data[] =
{
0xb3, 0x31, 0x2f, 0xa7, 0xe2, 0x3e, 0xe7, 0xe4,
0x98, 0x8e, 0x05, 0x6b, 0xe3, 0xf8, 0x2d, 0x19,
0x18, 0x1d, 0x9c, 0x6e, 0xfe, 0x81, 0x41, 0x12,
0x03, 0x14, 0x08, 0x8f, 0x50, 0x13, 0x87, 0x5a,
0xc6, 0x56, 0x39, 0x8d, 0x8a, 0x2e, 0xd1, 0x9d,
0x2a, 0x85, 0xc8, 0xed, 0xd3, 0xec, 0x2a, 0xef
};
uint8_t Gx_384_data[] =
{
0xaa, 0x87, 0xca, 0x22, 0xbe, 0x8b, 0x05, 0x37,
0x8e, 0xb1, 0xc7, 0x1e, 0xf3, 0x20, 0xad, 0x74,
0x6e, 0x1d, 0x3b, 0x62, 0x8b, 0xa7, 0x9b, 0x98,
0x59, 0xf7, 0x41, 0xe0, 0x82, 0x54, 0x2a, 0x38,
0x55, 0x02, 0xf2, 0x5d, 0xbf, 0x55, 0x29, 0x6c,
0x3a, 0x54, 0x5e, 0x38, 0x72, 0x76, 0x0a, 0xb7
};
uint8_t Gy_384_data[] =
{
0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f,
0x5d, 0x9e, 0x98, 0xbf, 0x92, 0x92, 0xdc, 0x29,
0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c,
0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0,
0x0a, 0x60, 0xb1, 0xce, 0x1d, 0x7e, 0x81, 0x9d,
0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f
};
uint8_t P_521_data[] =
{
0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF
};
uint8_t n_521_data[] =
{
0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFA, 0x51, 0x86, 0x87, 0x83, 0xBF, 0x2F,
0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C,
0x47, 0xAE, 0xBB, 0x6F, 0xB7, 0x1E, 0x91, 0x38,
0x64, 0x09
};
uint8_t b_521_data[] =
{
0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c,
0x9a, 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85,
0x40, 0xee, 0xa2, 0xda, 0x72, 0x5b, 0x99, 0xb3,
0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1,
0x09, 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e,
0x93, 0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1,
0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c,
0x34, 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50,
0x3f, 0x00
};
uint8_t Gx_521_data[] =
{
0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04,
0xe9, 0xcd, 0x9e, 0x3e, 0xcb, 0x66, 0x23, 0x95,
0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d,
0x3d, 0xba, 0xa1, 0x4b, 0x5e, 0x77, 0xef, 0xe7,
0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a,
0x42, 0x9b, 0xf9, 0x7e, 0x7e, 0x31, 0xc2, 0xe5,
0xbd, 0x66
};
uint8_t Gy_521_data[] =
{
0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b,
0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d,
0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e,
0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4,
0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72,
0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1,
0x66, 0x50
};
/*----------------------------------------------------------------------------*/
/* Initialize the curve parameters struct */
zrtp_status_t zrtp_ec_init_params( struct zrtp_ec_params *params, uint32_t bits )
{
unsigned ec_bytes = (bits+7) / 8;
params->ec_bits = bits;
switch (bits) {
case 256:
zrtp_memcpy (params->P_data, P_256_data, ec_bytes);
zrtp_memcpy (params->n_data, n_256_data, ec_bytes);
zrtp_memcpy (params->b_data, b_256_data, ec_bytes);
zrtp_memcpy (params->Gx_data, Gx_256_data, ec_bytes);
zrtp_memcpy (params->Gy_data, Gy_256_data, ec_bytes);
break;
case 384:
zrtp_memcpy (params->P_data, P_384_data, ec_bytes);
zrtp_memcpy (params->n_data, n_384_data, ec_bytes);
zrtp_memcpy (params->b_data, b_384_data, ec_bytes);
zrtp_memcpy (params->Gx_data, Gx_384_data, ec_bytes);
zrtp_memcpy (params->Gy_data, Gy_384_data, ec_bytes);
break;
case 521:
zrtp_memcpy (params->P_data, P_521_data, ec_bytes);
zrtp_memcpy (params->n_data, n_521_data, ec_bytes);
zrtp_memcpy (params->b_data, b_521_data, ec_bytes);
zrtp_memcpy (params->Gx_data, Gx_521_data, ec_bytes);
zrtp_memcpy (params->Gy_data, Gy_521_data, ec_bytes);
break;
default:
return zrtp_status_bad_param;
}
return zrtp_status_ok;
}
#endif /*ZRTP_ENABLE_EC*/

View File

@ -0,0 +1,567 @@
/*
* zrtp_crypto_ecdh.c - Elliptic Curve Diffie Hellman functions for ZRTP.
* NSA Suite B Elliptic Curves from NIST SP 800-56A and FIPS 186-3.
*
* Copyright (c) 2006-2009 Philip R. Zimmermann. All rights reserved.
* This is NOT licensed under the GPL or any other open source license.
* For licensing terms or other information,
* contact: Philip Zimmermann <prz@mit.edu>.
* For more contact information, see http://philzimmermann.com
*/
#include "zrtp.h"
#if (defined(ZRTP_ENABLE_EC) && (ZRTP_ENABLE_EC == 1))
#define _ZTU_ "zrtp ecdh"
static unsigned get_pbits(zrtp_pk_scheme_t *self)
{
switch (self->base.id) {
case ZRTP_PKTYPE_EC256P:
return 256;
break;
case ZRTP_PKTYPE_EC384P:
return 384;
break;
case ZRTP_PKTYPE_EC521P:
return 521;
break;
default:
return 0;
}
}
/*============================================================================*/
/* Shared Elliptic Curve functions */
/* */
/* The Elliptic Curve DH algorithm and key generation is from */
/* NIST SP 800-56A. The curves used are from NSA Suite B, which */
/* uses the same curves as ECDSA defined by FIPS 186-3, and are */
/* also defined in RFC 4753, sections 3.1 through 3.3. */
/* The validation procedures are from NIST SP 800-56A section 5.6.2.6, */
/* method 3, ECC Partial Validation. */
/*============================================================================*/
/*----------------------------------------------------------------------------*/
static zrtp_status_t zrtp_ecdh_init(void *s) {
return zrtp_status_ok;
}
static zrtp_status_t zrtp_ecdh_free(void *s) {
return zrtp_status_ok;
}
/*----------------------------------------------------------------------------*/
/* Return dh_cc->pv holding public value and dh_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 zrtp_ecdh_initialize( zrtp_pk_scheme_t *self,
zrtp_dh_crypto_context_t *dh_cc)
{
zrtp_status_t s = zrtp_status_fail;
struct BigNum P, Gx, Gy, n;
struct BigNum pkx, pky;
unsigned ec_bytes = 0;
unsigned pbits = 0;
struct zrtp_ec_params ec_params;
zrtp_time_t start_ts = zrtp_time_now();
if (!self || !dh_cc) {
return zrtp_status_bad_param;
}
pbits = get_pbits(self);
if (!pbits) {
return zrtp_status_bad_param;
}
zrtp_ec_init_params(&ec_params, pbits);
ec_bytes = (ec_params.ec_bits+7) / 8;
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(&dh_cc->sv);
s = zrtp_ec_random_point( self->base.zrtp, &P, &n, &Gx, &Gy,
&pkx, &pky, &dh_cc->sv,
NULL, 0);
if (zrtp_status_ok == s)
{
bnBegin(&dh_cc->pv);
bnCopy (&dh_cc->pv, &pkx);
bnLShift (&dh_cc->pv, pbits);
bnAdd (&dh_cc->pv, &pky);
}
bnEnd (&pkx);
bnEnd (&pky);
bnEnd (&P);
bnEnd (&Gx);
bnEnd (&Gy);
bnEnd (&n);
ZRTP_LOG(1,(_ZTU_,"\tDH TEST: zrtp_ecdh_initialize() for %.4s was executed by %llums.\n", self->base.type, zrtp_time_now()-start_ts));
return s;
}
/*----------------------------------------------------------------------------*/
/* Compute the shared dhresult as the X coordinate of the EC point. */
/*----------------------------------------------------------------------------*/
static zrtp_status_t zrtp_ecdh_compute( zrtp_pk_scheme_t *self,
zrtp_dh_crypto_context_t *dh_cc,
struct BigNum *dhresult,
struct BigNum *pv)
{
struct BigNum P;
struct BigNum pkx, pky, rsltx, rslty;
unsigned ec_bytes = 0;
unsigned pbits = 0;
struct zrtp_ec_params ec_params;
zrtp_time_t start_ts = zrtp_time_now();
if (!self || !dh_cc || !dhresult || !pv) {
return zrtp_status_bad_param;
}
pbits = get_pbits(self);
if (!pbits) {
return zrtp_status_bad_param;
}
zrtp_ec_init_params(&ec_params, pbits);
ec_bytes = (ec_params.ec_bits+7) / 8;
bnBegin(&P);
bnInsertBigBytes( &P, ec_params.P_data, 0, ec_bytes );
bnBegin (&pkx);
bnBegin (&pky);
bnBegin (&rsltx);
bnBegin (&rslty);
bnSetQ (&pkx, 1);
bnLShift (&pkx, pbits);
bnMod (&pky, pv, &pkx);
bnCopy (&pkx, pv);
bnRShift (&pkx, pbits);
zrtp_ecMul (&rsltx, &rslty, &dh_cc->sv, &pkx, &pky, &P);
bnCopy (dhresult, &rsltx);
bnEnd (&pkx);
bnEnd (&pky);
bnEnd (&rsltx);
bnEnd (&rslty);
bnEnd (&P);
ZRTP_LOG(1,(_ZTU_,"\tDH TEST: zrtp_ecdh_compute() for %.4s was executed by %llums.\n", self->base.type, zrtp_time_now()-start_ts));
return zrtp_status_ok;
}
/*----------------------------------------------------------------------------*/
/* ECC Partial Validation per NIST SP800-56A section 5.6.2.6 */
/*----------------------------------------------------------------------------*/
static zrtp_status_t zrtp_ecdh_validate( zrtp_pk_scheme_t *self,
struct BigNum *pv)
{
zrtp_status_t s = zrtp_status_fail;
struct BigNum P, b;
struct BigNum t1, t2;
struct BigNum pkx, pky, bnzero;
unsigned ec_bytes = 0;
unsigned pbits = 0;
struct zrtp_ec_params ec_params;
zrtp_time_t start_ts = zrtp_time_now();
if (!self || !pv) {
return zrtp_status_bad_param;
}
pbits = get_pbits(self);
if (!pbits) {
return zrtp_status_bad_param;
}
zrtp_ec_init_params(&ec_params, pbits);
ec_bytes = (ec_params.ec_bits+7) / 8;
bnBegin(&P);
bnInsertBigBytes( &P, ec_params.P_data, 0, ec_bytes );
bnBegin(&b);
bnInsertBigBytes( &b, ec_params.b_data, 0, ec_bytes );
bnBegin (&t1);
bnBegin (&t2);
bnBegin (&pkx);
bnBegin (&pky);
bnBegin (&bnzero);
bnSetQ (&pkx, 1);
bnLShift (&pkx, pbits);
bnMod (&pky, pv, &pkx);
bnCopy (&pkx, pv);
bnRShift (&pkx, pbits);
do{
/* Represent point at infinity by (0, 0), make sure it's not that */
if (bnCmp (&pkx, &bnzero) == 0 && bnCmp (&pky, &bnzero) == 0) {
break;
}
/* Check coordinates within range */
if (bnCmp (&pkx, &bnzero) < 0 || bnCmp (&pkx, &P) >= 0) {
break;
}
if (bnCmp (&pky, &bnzero) < 0 || bnCmp (&pky, &P) >= 0) {
break;
}
/* Check that point satisfies EC equation y^2 = x^3 - 3x + b, mod P */
bnSquareMod_ (&t1, &pky, &P);
bnSquareMod_ (&t2, &pkx, &P);
bnSubQMod_ (&t2, 3, &P);
bnMulMod_ (&t2, &t2, &pkx, &P);
bnAddMod_ (&t2, &b, &P);
if (bnCmp (&t1, &t2) != 0) {
break;
}
s = zrtp_status_ok;
} while (0);
bnEnd (&t1);
bnEnd (&t2);
bnEnd (&pkx);
bnEnd (&pky);
bnEnd (&bnzero);
bnEnd (&P);
bnEnd (&b);
ZRTP_LOG(1,(_ZTU_,"\tDH TEST: zrtp_ecdh_validate() for %.4s was executed by %llums.\n", self->base.type, zrtp_time_now()-start_ts));
return s;
}
/*============================================================================*/
/* P-256, 384, 521 (FIPS 186-3) support. See RFC 4753 3.1, 3.2, 3.3 */
/*============================================================================*/
static uint8_t sv256_data[] = {
0x81, 0x42, 0x64, 0x14, 0x5F, 0x2F, 0x56, 0xF2,
0xE9, 0x6A, 0x8E, 0x33, 0x7A, 0x12, 0x84, 0x99,
0x3F, 0xAF, 0x43, 0x2A, 0x5A, 0xBC, 0xE5, 0x9E,
0x86, 0x7B, 0x72, 0x91, 0xD5, 0x07, 0xA3, 0xAF
};
static uint8_t pvx256_data[] = {
0x2A, 0xF5, 0x02, 0xF3, 0xBE, 0x89, 0x52, 0xF2,
0xC9, 0xB5, 0xA8, 0xD4, 0x16, 0x0D, 0x09, 0xE9,
0x71, 0x65, 0xBE, 0x50, 0xBC, 0x42, 0xAE, 0x4A,
0x5E, 0x8D, 0x3B, 0x4B, 0xA8, 0x3A, 0xEB, 0x15
};
static uint8_t pvy256_data[] = {
0xEB, 0x0F, 0xAF, 0x4C, 0xA9, 0x86, 0xC4, 0xD3,
0x86, 0x81, 0xA0, 0xF9, 0x87, 0x2D, 0x79, 0xD5,
0x67, 0x95, 0xBD, 0x4B, 0xFF, 0x6E, 0x6D, 0xE3,
0xC0, 0xF5, 0x01, 0x5E, 0xCE, 0x5E, 0xFD, 0x85
};
static uint8_t sv384_data[] = {
0xD2, 0x73, 0x35, 0xEA, 0x71, 0x66, 0x4A, 0xF2,
0x44, 0xDD, 0x14, 0xE9, 0xFD, 0x12, 0x60, 0x71,
0x5D, 0xFD, 0x8A, 0x79, 0x65, 0x57, 0x1C, 0x48,
0xD7, 0x09, 0xEE, 0x7A, 0x79, 0x62, 0xA1, 0x56,
0xD7, 0x06, 0xA9, 0x0C, 0xBC, 0xB5, 0xDF, 0x29,
0x86, 0xF0, 0x5F, 0xEA, 0xDB, 0x93, 0x76, 0xF1
};
static uint8_t pvx384_data[] = {
0x79, 0x31, 0x48, 0xF1, 0x78, 0x76, 0x34, 0xD5,
0xDA, 0x4C, 0x6D, 0x90, 0x74, 0x41, 0x7D, 0x05,
0xE0, 0x57, 0xAB, 0x62, 0xF8, 0x20, 0x54, 0xD1,
0x0E, 0xE6, 0xB0, 0x40, 0x3D, 0x62, 0x79, 0x54,
0x7E, 0x6A, 0x8E, 0xA9, 0xD1, 0xFD, 0x77, 0x42,
0x7D, 0x01, 0x6F, 0xE2, 0x7A, 0x8B, 0x8C, 0x66
};
static uint8_t pvy384_data[] = {
0xC6, 0xC4, 0x12, 0x94, 0x33, 0x1D, 0x23, 0xE6,
0xF4, 0x80, 0xF4, 0xFB, 0x4C, 0xD4, 0x05, 0x04,
0xC9, 0x47, 0x39, 0x2E, 0x94, 0xF4, 0xC3, 0xF0,
0x6B, 0x8F, 0x39, 0x8B, 0xB2, 0x9E, 0x42, 0x36,
0x8F, 0x7A, 0x68, 0x59, 0x23, 0xDE, 0x3B, 0x67,
0xBA, 0xCE, 0xD2, 0x14, 0xA1, 0xA1, 0xD1, 0x28
};
static uint8_t sv521_data[] = {
0x01, 0x13, 0xF8, 0x2D, 0xA8, 0x25, 0x73, 0x5E,
0x3D, 0x97, 0x27, 0x66, 0x83, 0xB2, 0xB7, 0x42,
0x77, 0xBA, 0xD2, 0x73, 0x35, 0xEA, 0x71, 0x66,
0x4A, 0xF2, 0x43, 0x0C, 0xC4, 0xF3, 0x34, 0x59,
0xB9, 0x66, 0x9E, 0xE7, 0x8B, 0x3F, 0xFB, 0x9B,
0x86, 0x83, 0x01, 0x5D, 0x34, 0x4D, 0xCB, 0xFE,
0xF6, 0xFB, 0x9A, 0xF4, 0xC6, 0xC4, 0x70, 0xBE,
0x25, 0x45, 0x16, 0xCD, 0x3C, 0x1A, 0x1F, 0xB4,
0x73, 0x62
};
static uint8_t pvx521_data[] = {
0x01, 0xEB, 0xB3, 0x4D, 0xD7, 0x57, 0x21, 0xAB,
0xF8, 0xAD, 0xC9, 0xDB, 0xED, 0x17, 0x88, 0x9C,
0xBB, 0x97, 0x65, 0xD9, 0x0A, 0x7C, 0x60, 0xF2,
0xCE, 0xF0, 0x07, 0xBB, 0x0F, 0x2B, 0x26, 0xE1,
0x48, 0x81, 0xFD, 0x44, 0x42, 0xE6, 0x89, 0xD6,
0x1C, 0xB2, 0xDD, 0x04, 0x6E, 0xE3, 0x0E, 0x3F,
0xFD, 0x20, 0xF9, 0xA4, 0x5B, 0xBD, 0xF6, 0x41,
0x3D, 0x58, 0x3A, 0x2D, 0xBF, 0x59, 0x92, 0x4F,
0xD3, 0x5C
};
static uint8_t pvy521_data[] = {
0x00, 0xF6, 0xB6, 0x32, 0xD1, 0x94, 0xC0, 0x38,
0x8E, 0x22, 0xD8, 0x43, 0x7E, 0x55, 0x8C, 0x55,
0x2A, 0xE1, 0x95, 0xAD, 0xFD, 0x15, 0x3F, 0x92,
0xD7, 0x49, 0x08, 0x35, 0x1B, 0x2F, 0x8C, 0x4E,
0xDA, 0x94, 0xED, 0xB0, 0x91, 0x6D, 0x1B, 0x53,
0xC0, 0x20, 0xB5, 0xEE, 0xCA, 0xED, 0x1A, 0x5F,
0xC3, 0x8A, 0x23, 0x3E, 0x48, 0x30, 0x58, 0x7B,
0xB2, 0xEE, 0x34, 0x89, 0xB3, 0xB4, 0x2A, 0x5A,
0x86, 0xA4
};
zrtp_status_t zrtp_ecdh_selftest(zrtp_pk_scheme_t *self)
{
zrtp_status_t s = zrtp_status_fail;
struct BigNum P, Gx, Gy, n, sv;
struct BigNum pkx, pky;
unsigned ec_bytes = 0;
unsigned pbits = 0;
struct zrtp_ec_params ec_params;
zrtp_time_t start_ts = 0;
uint8_t *sv_data = NULL;
size_t sv_data_len = 0;
uint8_t *pvx_data = NULL;
size_t pvx_data_len = 0;
uint8_t *pvy_data = NULL;
size_t pvy_data_len = 0;
if (!self) {
return zrtp_status_bad_param;
}
ZRTP_LOG(3, (_ZTU_, "PKS %.4s testing... ", self->base.type));
switch (self->base.id) {
case ZRTP_PKTYPE_EC256P:
sv_data = sv256_data;
sv_data_len = sizeof(sv256_data);
pvx_data = pvx256_data;
pvx_data_len = sizeof(pvx256_data);
pvy_data = pvy256_data;
pvy_data_len = sizeof(pvy256_data);
break;
case ZRTP_PKTYPE_EC384P:
sv_data = sv384_data;
sv_data_len = sizeof(sv384_data);
pvx_data = pvx384_data;
pvx_data_len = sizeof(pvx384_data);
pvy_data = pvy384_data;
pvy_data_len = sizeof(pvy384_data);
break;
case ZRTP_PKTYPE_EC521P:
sv_data = sv521_data;
sv_data_len = sizeof(sv521_data);
pvx_data = pvx521_data;
pvx_data_len = sizeof(pvx521_data);
pvy_data = pvy521_data;
pvy_data_len = sizeof(pvy521_data);
break;
default:
return 0;
}
pbits = get_pbits(self);
if (!pbits) {
return zrtp_status_bad_param;
}
zrtp_ec_init_params(&ec_params, pbits);
ec_bytes = (ec_params.ec_bits+7) / 8;
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(&sv);
s = zrtp_ec_random_point( self->base.zrtp, &P, &n, &Gx, &Gy,
&pkx, &pky, &sv,
sv_data, sv_data_len);
if (zrtp_status_ok == s)
{
struct BigNum pkx1, pky1;
bnBegin(&pkx1); bnBegin(&pky1);
bnInsertBigBytes(&pkx1, pvx_data, 0, pvx_data_len);
bnInsertBigBytes(&pky1, pvy_data, 0, pvy_data_len);
s = (bnCmp (&pkx1, &pkx) == 0 && bnCmp (&pky1, &pky) == 0) ? zrtp_status_ok : zrtp_status_fail;
bnEnd(&pkx1);
bnEnd(&pky1);
}
bnEnd (&pkx);
bnEnd (&pky);
bnEnd (&P);
bnEnd (&Gx);
bnEnd (&Gy);
bnEnd (&n);
bnEnd (&sv);
if (zrtp_status_ok == s) {
zrtp_status_t s = zrtp_status_ok;
zrtp_dh_crypto_context_t alice_cc;
zrtp_dh_crypto_context_t bob_cc;
struct BigNum alice_k;
struct BigNum bob_k;
start_ts = zrtp_time_now();
bnBegin(&alice_k);
bnBegin(&bob_k);
do {
/* Both sides initalise DH schemes and compute secret and public values. */
s = self->initialize(self, &alice_cc);
if (zrtp_status_ok != s) {
break;
}
s = self->initialize(self, &bob_cc);
if (zrtp_status_ok != s) {
break;
}
/* Both sides validate public values. (to provide exact performance estimation) */
s = self->validate(self, &bob_cc.pv);
if (zrtp_status_ok != s) {
break;
}
s = self->validate(self, &alice_cc.pv);
if (zrtp_status_ok != s) {
break;
}
/* Compute secret keys and compare them. */
s = self->compute(self, &alice_cc, &alice_k, &bob_cc.pv);
if (zrtp_status_ok != s) {
break;
}
s= self->compute(self, &bob_cc, &bob_k, &alice_cc.pv);
if (zrtp_status_ok != s) {
break;
}
s = (0 == bnCmp(&alice_k, &bob_k)) ? zrtp_status_ok : zrtp_status_algo_fail;
} while (0);
bnEnd(&alice_k);
bnEnd(&bob_k);
}
ZRTP_LOGC(3, ("%s (%llu ms)\n", zrtp_log_status2str(s), (zrtp_time_now()-start_ts)/2));
return s;
}
/*============================================================================*/
/* Public Key support */
/*============================================================================*/
/*----------------------------------------------------------------------------*/
zrtp_status_t zrtp_defaults_ec_pkt(zrtp_global_t* zrtp)
{
zrtp_pk_scheme_t* ec256p = zrtp_sys_alloc(sizeof(zrtp_pk_scheme_t));
zrtp_pk_scheme_t* ec384p = zrtp_sys_alloc(sizeof(zrtp_pk_scheme_t));
zrtp_pk_scheme_t* ec521p = zrtp_sys_alloc(sizeof(zrtp_pk_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_pk_scheme_t));
zrtp_memcpy(ec256p->base.type, ZRTP_EC256P, ZRTP_COMP_TYPE_SIZE);
ec256p->base.id = ZRTP_PKTYPE_EC256P;
ec256p->base.zrtp = zrtp;
ec256p->sv_length = 256/8;
ec256p->pv_length = 2*256/8;
ec256p->base.init = zrtp_ecdh_init;
ec256p->base.free = zrtp_ecdh_free;
ec256p->initialize = zrtp_ecdh_initialize;
ec256p->compute = zrtp_ecdh_compute;
ec256p->validate = zrtp_ecdh_validate;
ec256p->self_test = zrtp_ecdh_selftest;
zrtp_memset(ec384p, 0, sizeof(zrtp_pk_scheme_t));
zrtp_memcpy(ec384p->base.type, ZRTP_EC384P, ZRTP_COMP_TYPE_SIZE);
ec384p->base.id = ZRTP_PKTYPE_EC384P;
ec384p->base.zrtp = zrtp;
ec384p->sv_length = 384/8;
ec384p->pv_length = 2*384/8;
ec384p->base.init = zrtp_ecdh_init;
ec384p->base.free = zrtp_ecdh_free;
ec384p->initialize = zrtp_ecdh_initialize;
ec384p->compute = zrtp_ecdh_compute;
ec384p->validate = zrtp_ecdh_validate;
ec384p->self_test = zrtp_ecdh_selftest;
zrtp_memset(ec521p, 0, sizeof(zrtp_pk_scheme_t));
zrtp_memcpy(ec521p->base.type, ZRTP_EC521P, ZRTP_COMP_TYPE_SIZE);
ec521p->base.id = ZRTP_PKTYPE_EC521P;
ec521p->base.zrtp = zrtp;
ec521p->sv_length = 528/8;
ec521p->pv_length = 2*528/8;
ec521p->base.init = zrtp_ecdh_init;
ec521p->base.free = zrtp_ecdh_free;
ec521p->initialize = zrtp_ecdh_initialize;
ec521p->compute = zrtp_ecdh_compute;
ec521p->validate = zrtp_ecdh_validate;
ec521p->self_test = zrtp_ecdh_selftest;
zrtp_comp_register(ZRTP_CC_PKT, ec256p, zrtp);
zrtp_comp_register(ZRTP_CC_PKT, ec384p, zrtp);
zrtp_comp_register(ZRTP_CC_PKT, ec521p, zrtp);
return zrtp_status_ok;
}
#endif /*ZRTP_ENABLE_EC*/

View File

@ -0,0 +1,646 @@
/*
* zrtp_crypto_ecdsa.c - Elliptic Curve Digital Signature functions for ZRTP.
* NSA Suite B Elliptic Curves from NIST SP 800-56A and FIPS 186-3.
*
* Copyright (c) 2006-2009 Philip R. Zimmermann. All rights reserved.
* This is NOT licensed under the GPL or any other open source license.
* For licensing terms or other information,
* contact: Philip Zimmermann <prz@mit.edu>.
* For more contact information, see http://philzimmermann.com
*/
#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(&params, 256);
return ECDSA_keygen(self, dsa_cc, &params,
#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(&params, 256);
return ECDSA_sign(self, dsa_cc, &params,
#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(&params, 256);
return ECDSA_verify(self, dsa_cc, &params,
#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(&params, 384);
return ECDSA_keygen(self, dsa_cc, &params,
#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(&params, 384);
return ECDSA_sign(self, dsa_cc, &params,
#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(&params, 384);
return ECDSA_verify(self, dsa_cc, &params, 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(&params, 521);
return ECDSA_keygen(self, dsa_cc, &params,
#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(&params, 521);
return ECDSA_sign(self, dsa_cc, &params,
#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(&params, 521);
return ECDSA_verify(self, dsa_cc, &params, 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*/