mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-03-13 12:40:17 +00:00
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:
parent
fafd8f337c
commit
8843819ce5
@ -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
|
||||
|
89
libs/libzrtp/include/zrtp_ec.h
Normal file
89
libs/libzrtp/include/zrtp_ec.h
Normal 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__ */
|
@ -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"
|
||||
>
|
||||
|
@ -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"
|
||||
>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
469
libs/libzrtp/src/zrtp_crypto_ec.c
Normal file
469
libs/libzrtp/src/zrtp_crypto_ec.c
Normal 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*/
|
567
libs/libzrtp/src/zrtp_crypto_ecdh.c
Normal file
567
libs/libzrtp/src/zrtp_crypto_ecdh.c
Normal 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*/
|
646
libs/libzrtp/src/zrtp_crypto_ecdsa.c
Normal file
646
libs/libzrtp/src/zrtp_crypto_ecdsa.c
Normal 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(¶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*/
|
Loading…
x
Reference in New Issue
Block a user