diff --git a/ctaocrypt/include/ctc_ecc.h b/ctaocrypt/include/ctc_ecc.h index 6a2cff301..5fd890f30 100644 --- a/ctaocrypt/include/ctc_ecc.h +++ b/ctaocrypt/include/ctc_ecc.h @@ -46,12 +46,12 @@ enum { /* ECC set type defined a NIST GF(p) curve */ typedef struct { int size; /* The size of the curve in octets */ - char* name; /* name of this curve */ - char* prime; /* prime that defines the field the curve is in (hex) */ - char* B; /* fields B param (hex) */ - char* order; /* order of the curve (hex) */ - char* Gx; /* x coordinate of the base point on curve (hex) */ - char* Gy; /* y coordinate of the base point on curve (hex) */ + const char* name; /* name of this curve */ + const char* prime; /* prime that defines the field, curve is in (hex) */ + const char* B; /* fields B param (hex) */ + const char* order; /* order of the curve (hex) */ + const char* Gx; /* x coordinate of the base point on curve (hex) */ + const char* Gy; /* y coordinate of the base point on curve (hex) */ } ecc_set_type; diff --git a/ctaocrypt/include/tfm.h b/ctaocrypt/include/tfm.h index d39d7f090..7cc052228 100644 --- a/ctaocrypt/include/tfm.h +++ b/ctaocrypt/include/tfm.h @@ -402,7 +402,7 @@ int fp_mod(fp_int *a, fp_int *b, fp_int *c); int fp_cmp_d(fp_int *a, fp_digit b); /* c = a + b */ -/*void fp_add_d(fp_int *a, fp_digit b, fp_int *c);*/ +void fp_add_d(fp_int *a, fp_digit b, fp_int *c); /* c = a - b */ /*void fp_sub_d(fp_int *a, fp_digit b, fp_int *c);*/ diff --git a/ctaocrypt/src/ecc.c b/ctaocrypt/src/ecc.c index 9f03ed2f2..bd5cb7108 100644 --- a/ctaocrypt/src/ecc.c +++ b/ctaocrypt/src/ecc.c @@ -1 +1,1516 @@ -/* dummy ecc.c for dist */ +/* ecc.c + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * CyaSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +#ifdef HAVE_ECC + +#include "ctc_ecc.h" +#include "asn.h" +#include "error.h" + + +/* map + + ptmul -> mulmod + +*/ + +#define ECC112 +#define ECC128 +#define ECC160 +#define ECC192 +#define ECC224 +#define ECC256 +#define ECC384 +#define ECC521 + + + +/* This holds the key settings. ***MUST*** be organized by size from + smallest to largest. */ + +const ecc_set_type ecc_sets[] = { +#ifdef ECC112 +{ + 14, + "SECP112R1", + "DB7C2ABF62E35E668076BEAD208B", + "659EF8BA043916EEDE8911702B22", + "DB7C2ABF62E35E7628DFAC6561C5", + "09487239995A5EE76B55F9C2F098", + "A89CE5AF8724C0A23E0E0FF77500" +}, +#endif +#ifdef ECC128 +{ + 16, + "SECP128R1", + "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", + "E87579C11079F43DD824993C2CEE5ED3", + "FFFFFFFE0000000075A30D1B9038A115", + "161FF7528B899B2D0C28607CA52C5B86", + "CF5AC8395BAFEB13C02DA292DDED7A83", +}, +#endif +#ifdef ECC160 +{ + 20, + "SECP160R1", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", + "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", + "0100000000000000000001F4C8F927AED3CA752257", + "4A96B5688EF573284664698968C38BB913CBFC82", + "23A628553168947D59DCC912042351377AC5FB32", +}, +#endif +#ifdef ECC192 +{ + 24, + "ECC-192", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", + "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", + "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", + "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", + "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811", +}, +#endif +#ifdef ECC224 +{ + 28, + "ECC-224", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", + "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", + "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", + "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", +}, +#endif +#ifdef ECC256 +{ + 32, + "ECC-256", + "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", + "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", + "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", + "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", +}, +#endif +#ifdef ECC384 +{ + 48, + "ECC-384", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", + "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", + "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", + "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", +}, +#endif +#ifdef ECC521 +{ + 66, + "ECC-521", + "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", + "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", + "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", + "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", +}, +#endif +{ + 0, + NULL, NULL, NULL, NULL, NULL, NULL +} +}; + + +ecc_point* ecc_new_point(void); +void ecc_del_point(ecc_point* p); +int ecc_map(ecc_point*, mp_int*, mp_digit*); +int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R, + mp_int* modulus, mp_digit* mp); +int ecc_projective_dbl_point(ecc_point* P, ecc_point* R, mp_int* modulus, + mp_digit* mp); + + +/* helper for either lib */ +static int get_digit_count(mp_int* a) +{ + if (a == NULL) + return 0; + + return a->used; +} + +/* helper for either lib */ +static unsigned long get_digit(mp_int* a, int n) +{ + if (a == NULL) + return 0; + + return (n >= a->used || n < 0) ? 0 : a->dp[n]; +} + + +/** + Add two ECC points + P The point to add + Q The point to add + R [out] The destination of the double + modulus The modulus of the field the ECC curve is in + mp The "b" value from montgomery_setup() + return MP_OKAY on success +*/ +int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R, + mp_int* modulus, mp_digit* mp) +{ + mp_int t1; + mp_int t2; + mp_int x; + mp_int y; + mp_int z; + int err; + + if (P == NULL || Q == NULL || R == NULL || modulus == NULL || mp == NULL) + return ECC_BAD_ARG_E; + + if ((err = mp_init_multi(&t1, &t2, &x, &y, &z, NULL)) != MP_OKAY) { + return err; + } + + /* should we dbl instead? */ + err = mp_sub(modulus, &Q->y, &t1); + + if (err == MP_OKAY) { + if ( (mp_cmp(&P->x, &Q->x) == MP_EQ) && + (get_digit_count(&Q->z) && mp_cmp(&P->z, &Q->z) == MP_EQ) && + (mp_cmp(&P->y, &Q->y) == MP_EQ || mp_cmp(&P->y, &t1) == MP_EQ)) { + mp_clear(&t1); + mp_clear(&t2); + mp_clear(&x); + mp_clear(&y); + mp_clear(&z); + + return ecc_projective_dbl_point(P, R, modulus, mp); + } + } + + if (err == MP_OKAY) + err = mp_copy(&P->x, &x); + if (err == MP_OKAY) + err = mp_copy(&P->y, &y); + if (err == MP_OKAY) + err = mp_copy(&P->z, &z); + + /* if Z is one then these are no-operations */ + if (err == MP_OKAY) { + if (get_digit_count(&Q->z)) { + /* T1 = Z' * Z' */ + err = mp_sqr(&Q->z, &t1); + if (err == MP_OKAY) + err = mp_montgomery_reduce(&t1, modulus, *mp); + + /* X = X * T1 */ + if (err == MP_OKAY) + err = mp_mul(&t1, &x, &x); + if (err == MP_OKAY) + err = mp_montgomery_reduce(&x, modulus, *mp); + + /* T1 = Z' * T1 */ + if (err == MP_OKAY) + err = mp_mul(&Q->z, &t1, &t1); + if (err == MP_OKAY) + err = mp_montgomery_reduce(&t1, modulus, *mp); + + /* Y = Y * T1 */ + if (err == MP_OKAY) + err = mp_mul(&t1, &y, &y); + if (err == MP_OKAY) + err = mp_montgomery_reduce(&y, modulus, *mp); + } + } + + /* T1 = Z*Z */ + if (err == MP_OKAY) + err = mp_sqr(&z, &t1); + if (err == MP_OKAY) + err = mp_montgomery_reduce(&t1, modulus, *mp); + + /* T2 = X' * T1 */ + if (err == MP_OKAY) + err = mp_mul(&Q->x, &t1, &t2); + if (err == MP_OKAY) + err = mp_montgomery_reduce(&t2, modulus, *mp); + + /* T1 = Z * T1 */ + if (err == MP_OKAY) + err = mp_mul(&z, &t1, &t1); + if (err == MP_OKAY) + err = mp_montgomery_reduce(&t1, modulus, *mp); + + /* T1 = Y' * T1 */ + if (err == MP_OKAY) + err = mp_mul(&Q->y, &t1, &t1); + if (err == MP_OKAY) + err = mp_montgomery_reduce(&t1, modulus, *mp); + + /* Y = Y - T1 */ + if (err == MP_OKAY) + err = mp_sub(&y, &t1, &y); + if (err == MP_OKAY) { + if (mp_cmp_d(&y, 0) == MP_LT) + err = mp_add(&y, modulus, &y); + } + /* T1 = 2T1 */ + if (err == MP_OKAY) + err = mp_add(&t1, &t1, &t1); + if (err == MP_OKAY) { + if (mp_cmp(&t1, modulus) != MP_LT) + err = mp_sub(&t1, modulus, &t1); + } + /* T1 = Y + T1 */ + if (err == MP_OKAY) + err = mp_add(&t1, &y, &t1); + if (err == MP_OKAY) { + if (mp_cmp(&t1, modulus) != MP_LT) + err = mp_sub(&t1, modulus, &t1); + } + /* X = X - T2 */ + if (err == MP_OKAY) + err = mp_sub(&x, &t2, &x); + if (err == MP_OKAY) { + if (mp_cmp_d(&x, 0) == MP_LT) + err = mp_add(&x, modulus, &x); + } + /* T2 = 2T2 */ + if (err == MP_OKAY) + err = mp_add(&t2, &t2, &t2); + if (err == MP_OKAY) { + if (mp_cmp(&t2, modulus) != MP_LT) + err = mp_sub(&t2, modulus, &t2); + } + /* T2 = X + T2 */ + if (err == MP_OKAY) + err = mp_add(&t2, &x, &t2); + if (err == MP_OKAY) { + if (mp_cmp(&t2, modulus) != MP_LT) + err = mp_sub(&t2, modulus, &t2); + } + + if (err == MP_OKAY) { + if (get_digit_count(&Q->z)) { + /* Z = Z * Z' */ + err = mp_mul(&z, &Q->z, &z); + if (err == MP_OKAY) + err = mp_montgomery_reduce(&z, modulus, *mp); + } + } + + /* Z = Z * X */ + if (err == MP_OKAY) + err = mp_mul(&z, &x, &z); + if (err == MP_OKAY) + err = mp_montgomery_reduce(&z, modulus, *mp); + + /* T1 = T1 * X */ + if (err == MP_OKAY) + err = mp_mul(&t1, &x, &t1); + if (err == MP_OKAY) + err = mp_montgomery_reduce(&t1, modulus, *mp); + + /* X = X * X */ + if (err == MP_OKAY) + err = mp_sqr(&x, &x); + if (err == MP_OKAY) + err = mp_montgomery_reduce(&x, modulus, *mp); + + /* T2 = T2 * x */ + if (err == MP_OKAY) + err = mp_mul(&t2, &x, &t2); + if (err == MP_OKAY) + err = mp_montgomery_reduce(&t2, modulus, *mp); + + /* T1 = T1 * X */ + if (err == MP_OKAY) + err = mp_mul(&t1, &x, &t1); + if (err == MP_OKAY) + err = mp_montgomery_reduce(&t1, modulus, *mp); + + /* X = Y*Y */ + if (err == MP_OKAY) + err = mp_sqr(&y, &x); + if (err == MP_OKAY) + err = mp_montgomery_reduce(&x, modulus, *mp); + + /* X = X - T2 */ + if (err == MP_OKAY) + err = mp_sub(&x, &t2, &x); + if (err == MP_OKAY) { + if (mp_cmp_d(&x, 0) == MP_LT) + err = mp_add(&x, modulus, &x); + } + /* T2 = T2 - X */ + if (err == MP_OKAY) + err = mp_sub(&t2, &x, &t2); + if (err == MP_OKAY) { + if (mp_cmp_d(&t2, 0) == MP_LT) + err = mp_add(&t2, modulus, &t2); + } + /* T2 = T2 - X */ + if (err == MP_OKAY) + err = mp_sub(&t2, &x, &t2); + if (err == MP_OKAY) { + if (mp_cmp_d(&t2, 0) == MP_LT) + err = mp_add(&t2, modulus, &t2); + } + /* T2 = T2 * Y */ + if (err == MP_OKAY) + err = mp_mul(&t2, &y, &t2); + if (err == MP_OKAY) + err = mp_montgomery_reduce(&t2, modulus, *mp); + + /* Y = T2 - T1 */ + if (err == MP_OKAY) + err = mp_sub(&t2, &t1, &y); + if (err == MP_OKAY) { + if (mp_cmp_d(&y, 0) == MP_LT) + err = mp_add(&y, modulus, &y); + } + /* Y = Y/2 */ + if (err == MP_OKAY) { + if (mp_isodd(&y)) + err = mp_add(&y, modulus, &y); + } + if (err == MP_OKAY) + err = mp_div_2(&y, &y); + + if (err == MP_OKAY) + err = mp_copy(&x, &R->x); + if (err == MP_OKAY) + err = mp_copy(&y, &R->y); + if (err == MP_OKAY) + err = mp_copy(&z, &R->z); + + /* clean up */ + mp_clear(&t1); + mp_clear(&t2); + mp_clear(&x); + mp_clear(&y); + mp_clear(&z); + + return err; +} + + +/** + Double an ECC point + P The point to double + R [out] The destination of the double + modulus The modulus of the field the ECC curve is in + mp The "b" value from montgomery_setup() + return MP_OKAY on success +*/ +int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* modulus, + mp_digit* mp) +{ + mp_int t1; + mp_int t2; + int err; + + if (P == NULL || R == NULL || modulus == NULL || mp == NULL) + return ECC_BAD_ARG_E; + + if ((err = mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) { + return err; + } + + if (P != R) { + err = mp_copy(&P->x, &R->x); + if (err == MP_OKAY) + err = mp_copy(&P->y, &R->y); + if (err == MP_OKAY) + err = mp_copy(&P->z, &R->z); + } + + /* t1 = Z * Z */ + if (err == MP_OKAY) + err = mp_sqr(&R->z, &t1); + if (err == MP_OKAY) + err = mp_montgomery_reduce(&t1, modulus, *mp); + + /* Z = Y * Z */ + if (err == MP_OKAY) + err = mp_mul(&R->z, &R->y, &R->z); + if (err == MP_OKAY) + err = mp_montgomery_reduce(&R->z, modulus, *mp); + + /* Z = 2Z */ + if (err == MP_OKAY) + err = mp_add(&R->z, &R->z, &R->z); + if (err == MP_OKAY) { + if (mp_cmp(&R->z, modulus) != MP_LT) + err = mp_sub(&R->z, modulus, &R->z); + } + + /* T2 = X - T1 */ + if (err == MP_OKAY) + err = mp_sub(&R->x, &t1, &t2); + if (err == MP_OKAY) { + if (mp_cmp_d(&t2, 0) == MP_LT) + err = mp_add(&t2, modulus, &t2); + } + /* T1 = X + T1 */ + if (err == MP_OKAY) + err = mp_add(&t1, &R->x, &t1); + if (err == MP_OKAY) { + if (mp_cmp(&t1, modulus) != MP_LT) + err = mp_sub(&t1, modulus, &t1); + } + /* T2 = T1 * T2 */ + if (err == MP_OKAY) + err = mp_mul(&t1, &t2, &t2); + if (err == MP_OKAY) + err = mp_montgomery_reduce(&t2, modulus, *mp); + + /* T1 = 2T2 */ + if (err == MP_OKAY) + err = mp_add(&t2, &t2, &t1); + if (err == MP_OKAY) { + if (mp_cmp(&t1, modulus) != MP_LT) + err = mp_sub(&t1, modulus, &t1); + } + /* T1 = T1 + T2 */ + if (err == MP_OKAY) + err = mp_add(&t1, &t2, &t1); + if (err == MP_OKAY) { + if (mp_cmp(&t1, modulus) != MP_LT) + err = mp_sub(&t1, modulus, &t1); + } + /* Y = 2Y */ + if (err == MP_OKAY) + err = mp_add(&R->y, &R->y, &R->y); + if (err == MP_OKAY) { + if (mp_cmp(&R->y, modulus) != MP_LT) + err = mp_sub(&R->y, modulus, &R->y); + } + /* Y = Y * Y */ + if (err == MP_OKAY) + err = mp_sqr(&R->y, &R->y); + if (err == MP_OKAY) + err = mp_montgomery_reduce(&R->y, modulus, *mp); + + /* T2 = Y * Y */ + if (err == MP_OKAY) + err = mp_sqr(&R->y, &t2); + if (err == MP_OKAY) + err = mp_montgomery_reduce(&t2, modulus, *mp); + + /* T2 = T2/2 */ + if (err == MP_OKAY) { + if (mp_isodd(&t2)) + err = mp_add(&t2, modulus, &t2); + } + if (err == MP_OKAY) + err = mp_div_2(&t2, &t2); + + /* Y = Y * X */ + if (err == MP_OKAY) + err = mp_mul(&R->y, &R->x, &R->y); + if (err == MP_OKAY) + err = mp_montgomery_reduce(&R->y, modulus, *mp); + + /* X = T1 * T1 */ + if (err == MP_OKAY) + err = mp_sqr(&t1, &R->x); + if (err == MP_OKAY) + err = mp_montgomery_reduce(&R->x, modulus, *mp); + + /* X = X - Y */ + if (err == MP_OKAY) + err = mp_sub(&R->x, &R->y, &R->x); + if (err == MP_OKAY) { + if (mp_cmp_d(&R->x, 0) == MP_LT) + err = mp_add(&R->x, modulus, &R->x); + } + /* X = X - Y */ + if (err == MP_OKAY) + err = mp_sub(&R->x, &R->y, &R->x); + if (err == MP_OKAY) { + if (mp_cmp_d(&R->x, 0) == MP_LT) + err = mp_add(&R->x, modulus, &R->x); + } + /* Y = Y - X */ + if (err == MP_OKAY) + err = mp_sub(&R->y, &R->x, &R->y); + if (err == MP_OKAY) { + if (mp_cmp_d(&R->y, 0) == MP_LT) + err = mp_add(&R->y, modulus, &R->y); + } + /* Y = Y * T1 */ + if (err == MP_OKAY) + err = mp_mul(&R->y, &t1, &R->y); + if (err == MP_OKAY) + err = mp_montgomery_reduce(&R->y, modulus, *mp); + + /* Y = Y - T2 */ + if (err == MP_OKAY) + err = mp_sub(&R->y, &t2, &R->y); + if (err == MP_OKAY) { + if (mp_cmp_d(&R->y, 0) == MP_LT) + err = mp_add(&R->y, modulus, &R->y); + } + + /* clean up */ + mp_clear(&t1); + mp_clear(&t2); + + return err; +} + + +/** + Map a projective jacbobian point back to affine space + P [in/out] The point to map + modulus The modulus of the field the ECC curve is in + mp The "b" value from montgomery_setup() + return MP_OKAY on success +*/ +int ecc_map(ecc_point* P, mp_int* modulus, mp_digit* mp) +{ + mp_int t1; + mp_int t2; + int err; + + if (P == NULL || mp == NULL || modulus == NULL) + return ECC_BAD_ARG_E; + + if ((err = mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) { + return MEMORY_E; + } + + /* first map z back to normal */ + err = mp_montgomery_reduce(&P->z, modulus, *mp); + + /* get 1/z */ + if (err == MP_OKAY) + err = mp_invmod(&P->z, modulus, &t1); + + /* get 1/z^2 and 1/z^3 */ + if (err == MP_OKAY) + err = mp_sqr(&t1, &t2); + if (err == MP_OKAY) + err = mp_mod(&t2, modulus, &t2); + if (err == MP_OKAY) + err = mp_mul(&t1, &t2, &t1); + if (err == MP_OKAY) + err = mp_mod(&t1, modulus, &t1); + + /* multiply against x/y */ + if (err == MP_OKAY) + err = mp_mul(&P->x, &t2, &P->x); + if (err == MP_OKAY) + err = mp_montgomery_reduce(&P->x, modulus, *mp); + if (err == MP_OKAY) + err = mp_mul(&P->y, &t1, &P->y); + if (err == MP_OKAY) + err = mp_montgomery_reduce(&P->y, modulus, *mp); + + if (err == MP_OKAY) + mp_set(&P->z, 1); + + /* clean up */ + mp_clear(&t1); + mp_clear(&t2); + + return err; +} + + +#ifndef ECC_TIMING_RESISTANT + +/* size of sliding window, don't change this! */ +#define WINSIZE 4 + +/** + Perform a point multiplication + k The scalar to multiply by + G The base point + R [out] Destination for kG + modulus The modulus of the field the ECC curve is in + map Boolean whether to map back to affine or not + (1==map, 0 == leave in projective) + return MP_OKAY on success +*/ +static int ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus, + int map) +{ + ecc_point *tG, *M[8]; + int i, j, err; + mp_int mu; + mp_digit mp; + unsigned long buf; + int first, bitbuf, bitcpy, bitcnt, mode, digidx; + + if (k == NULL || G == NULL || R == NULL || modulus == NULL) + return ECC_BAD_ARG_E; + + /* init montgomery reduction */ + if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) { + return err; + } + if ((err = mp_init(&mu)) != MP_OKAY) { + return err; + } + if ((err = mp_montgomery_calc_normalization(&mu, modulus)) != MP_OKAY) { + mp_clear(&mu); + return err; + } + + /* alloc ram for window temps */ + for (i = 0; i < 8; i++) { + M[i] = ecc_new_point(); + if (M[i] == NULL) { + for (j = 0; j < i; j++) { + ecc_del_point(M[j]); + } + mp_clear(&mu); + return MEMORY_E; + } + } + + /* make a copy of G incase R==G */ + tG = ecc_new_point(); + if (tG == NULL) + err = MEMORY_E; + + /* tG = G and convert to montgomery */ + if (err == MP_OKAY) { + if (mp_cmp_d(&mu, 1) == MP_EQ) { + err = mp_copy(&G->x, &tG->x); + if (err == MP_OKAY) + err = mp_copy(&G->y, &tG->y); + if (err == MP_OKAY) + err = mp_copy(&G->z, &tG->z); + } else { + err = mp_mulmod(&G->x, &mu, modulus, &tG->x); + if (err == MP_OKAY) + err = mp_mulmod(&G->y, &mu, modulus, &tG->y); + if (err == MP_OKAY) + err = mp_mulmod(&G->z, &mu, modulus, &tG->z); + } + } + mp_clear(&mu); + + /* calc the M tab, which holds kG for k==8..15 */ + /* M[0] == 8G */ + if (err == MP_OKAY) + err = ecc_projective_dbl_point(tG, M[0], modulus, &mp); + if (err == MP_OKAY) + err = ecc_projective_dbl_point(M[0], M[0], modulus, &mp); + if (err == MP_OKAY) + err = ecc_projective_dbl_point(M[0], M[0], modulus, &mp); + + /* now find (8+k)G for k=1..7 */ + if (err == MP_OKAY) + for (j = 9; j < 16; j++) { + err = ecc_projective_add_point(M[j-9], tG, M[j-8], modulus, &mp); + if (err != MP_OKAY) break; + } + + /* setup sliding window */ + if (err == MP_OKAY) { + mode = 0; + bitcnt = 1; + buf = 0; + digidx = get_digit_count(k) - 1; + bitcpy = bitbuf = 0; + first = 1; + + /* perform ops */ + for (;;) { + /* grab next digit as required */ + if (--bitcnt == 0) { + if (digidx == -1) { + break; + } + buf = get_digit(k, digidx); + bitcnt = (int) DIGIT_BIT; + --digidx; + } + + /* grab the next msb from the ltiplicand */ + i = (buf >> (DIGIT_BIT - 1)) & 1; + buf <<= 1; + + /* skip leading zero bits */ + if (mode == 0 && i == 0) + continue; + + /* if the bit is zero and mode == 1 then we double */ + if (mode == 1 && i == 0) { + err = ecc_projective_dbl_point(R, R, modulus, &mp); + if (err != MP_OKAY) break; + continue; + } + + /* else we add it to the window */ + bitbuf |= (i << (WINSIZE - ++bitcpy)); + mode = 2; + + if (bitcpy == WINSIZE) { + /* if this is the first window we do a simple copy */ + if (first == 1) { + /* R = kG [k = first window] */ + err = mp_copy(&M[bitbuf-8]->x, &R->x); + if (err != MP_OKAY) break; + + err = mp_copy(&M[bitbuf-8]->y, &R->y); + if (err != MP_OKAY) break; + + err = mp_copy(&M[bitbuf-8]->z, &R->z); + first = 0; + } else { + /* normal window */ + /* ok window is filled so double as required and add */ + /* double first */ + for (j = 0; j < WINSIZE; j++) { + err = ecc_projective_dbl_point(R, R, modulus, &mp); + if (err != MP_OKAY) break; + } + if (err != MP_OKAY) break; /* out of first for(;;) */ + + /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranted */ + err = ecc_projective_add_point(R,M[bitbuf-8],R,modulus,&mp); + } + if (err != MP_OKAY) break; + /* empty window and reset */ + bitcpy = bitbuf = 0; + mode = 1; + } + } + } + + /* if bits remain then double/add */ + if (err == MP_OKAY) { + if (mode == 2 && bitcpy > 0) { + /* double then add */ + for (j = 0; j < bitcpy; j++) { + /* only double if we have had at least one add first */ + if (first == 0) { + err = ecc_projective_dbl_point(R, R, modulus, &mp); + if (err != MP_OKAY) break; + } + + bitbuf <<= 1; + if ((bitbuf & (1 << WINSIZE)) != 0) { + if (first == 1) { + /* first add, so copy */ + err = mp_copy(&tG->x, &R->x); + if (err != MP_OKAY) break; + + err = mp_copy(&tG->y, &R->y); + if (err != MP_OKAY) break; + + err = mp_copy(&tG->z, &R->z); + if (err != MP_OKAY) break; + first = 0; + } else { + /* then add */ + err = ecc_projective_add_point(R, tG, R, modulus, &mp); + if (err != MP_OKAY) break; + } + } + } + } + } + + /* map R back from projective space */ + if (err == MP_OKAY && map) + err = ecc_map(R, modulus, &mp); + + mp_clear(&mu); + ecc_del_point(tG); + for (i = 0; i < 8; i++) { + ecc_del_point(M[i]); + } + return err; +} + +#undef WINSIZE +#endif /* ECC_TIMING_RESISTANT */ + + +/** + Allocate a new ECC point + return A newly allocated point or NULL on error +*/ +ecc_point* ecc_new_point(void) +{ + ecc_point* p; + p = XMALLOC(sizeof(ecc_point), 0, DYNAMIC_TYPE_BIGINT); + if (p == NULL) { + return NULL; + } + XMEMSET(p, 0, sizeof(ecc_point)); + if (mp_init_multi(&p->x, &p->y, &p->z, NULL, NULL, NULL) != MP_OKAY) { + XFREE(p, 0, DYNAMIC_TYPE_BIGINT); + return NULL; + } + return p; +} + +/** Free an ECC point from memory + p The point to free +*/ +void ecc_del_point(ecc_point* p) +{ + /* prevents free'ing null arguments */ + if (p != NULL) { + mp_clear(&p->x); + mp_clear(&p->y); + mp_clear(&p->z); + XFREE(p, 0, DYNAMIC_TYPE_BIGINT); + } +} + + +/** Returns whether an ECC idx is valid or not + n The idx number to check + return 1 if valid, 0 if not +*/ +static int ecc_is_valid_idx(int n) +{ + int x; + + for (x = 0; ecc_sets[x].size != 0; x++) + ; + /* -1 is a valid index --- indicating that the domain params + were supplied by the user */ + if ((n >= -1) && (n < x)) { + return 1; + } + return 0; +} + + +/** + Create an ECC shared secret between two keys + private_key The private ECC key + public_key The public key + out [out] Destination of the shared secret + Conforms to EC-DH from ANSI X9.63 + outlen [in/out] The max size and resulting size of the shared secret + return MP_OKAY if successful +*/ +int ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, + word32* outlen) +{ + word32 x; + ecc_point* result; + mp_int prime; + int err; + + if (private_key == NULL || public_key == NULL || out == NULL || + outlen == NULL) + return BAD_FUNC_ARG; + + /* type valid? */ + if (private_key->type != ECC_PRIVATEKEY) { + return ECC_BAD_ARG_E; + } + + if (ecc_is_valid_idx(private_key->idx) == 0 || + ecc_is_valid_idx(public_key->idx) == 0) + return ECC_BAD_ARG_E; + + if (XSTRNCMP(private_key->dp->name, public_key->dp->name, ECC_MAXNAME) != 0) + return ECC_BAD_ARG_E; + + /* make new point */ + result = ecc_new_point(); + if (result == NULL) { + return MEMORY_E; + } + + if ((err = mp_init(&prime)) != MP_OKAY) { + ecc_del_point(result); + return err; + } + + err = mp_read_radix(&prime, (char *)private_key->dp->prime, 16); + + if (err == MP_OKAY) + err = ecc_mulmod(&private_key->k, &public_key->pubkey, result, &prime,1); + + if (err == MP_OKAY) { + x = (unsigned long)mp_unsigned_bin_size(&prime); + if (*outlen < x) + err = BUFFER_E; + } + + if (err == MP_OKAY) { + XMEMSET(out, 0, x); + err = mp_to_unsigned_bin(&result->x,out + (x - + mp_unsigned_bin_size(&result->x))); + *outlen = x; + } + + mp_clear(&prime); + ecc_del_point(result); + + return err; +} + + +int ecc_make_key_ex(RNG* rng, ecc_key* key, const ecc_set_type* dp); + +/** + Make a new ECC key + prng An active PRNG state + wprng The index of the PRNG you wish to use + keysize The keysize for the new key (in octets from 20 to 65 bytes) + key [out] Destination of the newly created key + return MP_OKAY if successful, + upon error all allocated memory will be freed +*/ +int ecc_make_key(RNG* rng, int keysize, ecc_key* key) +{ + int x, err; + + /* find key size */ + for (x = 0; (keysize > ecc_sets[x].size) && (ecc_sets[x].size != 0); x++) + ; + keysize = ecc_sets[x].size; + + if (keysize > ECC_MAXSIZE || ecc_sets[x].size == 0) { + return BAD_FUNC_ARG; + } + err = ecc_make_key_ex(rng, key, &ecc_sets[x]); + key->idx = x; + + return err; +} + +int ecc_make_key_ex(RNG* rng, ecc_key* key, const ecc_set_type* dp) +{ + int err; + ecc_point* base; + mp_int prime; + mp_int order; + byte buf[ECC_MAXSIZE]; + int keysize; + + if (key == NULL || rng == NULL || dp == NULL) + return ECC_BAD_ARG_E; + + key->idx = -1; + key->dp = dp; + keysize = dp->size; + + /* allocate ram */ + base = NULL; + + /* make up random string */ + RNG_GenerateBlock(rng, buf, keysize); + buf[0] |= 0x0c; + + /* setup the key variables */ + if ((err = mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, + &key->k, &prime, &order)) != MP_OKAY) + return MEMORY_E; + + base = ecc_new_point(); + if (base == NULL) + err = MEMORY_E; + + /* read in the specs for this key */ + if (err == MP_OKAY) + err = mp_read_radix(&prime, (char *)key->dp->prime, 16); + if (err == MP_OKAY) + err = mp_read_radix(&order, (char *)key->dp->order, 16); + if (err == MP_OKAY) + err = mp_read_radix(&base->x, (char *)key->dp->Gx, 16); + if (err == MP_OKAY) + err = mp_read_radix(&base->y, (char *)key->dp->Gy, 16); + + if (err == MP_OKAY) + mp_set(&base->z, 1); + if (err == MP_OKAY) + err = mp_read_unsigned_bin(&key->k, (byte*)buf, keysize); + + /* the key should be smaller than the order of base point */ + if (err == MP_OKAY) { + if (mp_cmp(&key->k, &order) != MP_LT) + err = mp_mod(&key->k, &order, &key->k); + } + /* make the public key */ + if (err == MP_OKAY) + err = ecc_mulmod(&key->k, base, &key->pubkey, &prime, 1); + if (err == MP_OKAY) + key->type = ECC_PRIVATEKEY; + + if (err != MP_OKAY) { + /* clean up */ + mp_clear(&key->pubkey.x); + mp_clear(&key->pubkey.y); + mp_clear(&key->pubkey.z); + mp_clear(&key->k); + } + ecc_del_point(base); + mp_clear(&prime); + mp_clear(&order); +#ifdef ECC_CLEAN_STACK + XMEMSET(buff, 0, ECC_MAXSIZE); +#endif + return err; +} + + +/* Setup dynamic pointers is using normal math for proper freeing */ +void ecc_init(ecc_key* key) +{ +#ifndef USE_FAST_MATH + key->pubkey.x.dp = NULL; + key->pubkey.y.dp = NULL; + key->pubkey.z.dp = NULL; + + key->k.dp = NULL; +#endif +} + + +/** + Sign a message digest + in The message digest to sign + inlen The length of the digest + out [out] The destination for the signature + outlen [in/out] The max size and resulting size of the signature + key A private ECC key + return MP_OKAY if successful +*/ +int ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, + RNG* rng, ecc_key* key) +{ + mp_int r; + mp_int s; + mp_int e; + mp_int p; + int err; + + if (in == NULL || out == NULL || outlen == NULL || key == NULL || rng ==NULL) + return ECC_BAD_ARG_E; + + /* is this a private key? */ + if (key->type != ECC_PRIVATEKEY) { + return ECC_BAD_ARG_E; + } + + /* is the IDX valid ? */ + if (ecc_is_valid_idx(key->idx) != 1) { + return ECC_BAD_ARG_E; + } + + /* get the hash and load it as a bignum into 'e' */ + /* init the bignums */ + if ((err = mp_init_multi(&r, &s, &p, &e, NULL, NULL)) != MP_OKAY) { + return err; + } + err = mp_read_radix(&p, (char *)key->dp->order, 16); + + if (err == MP_OKAY) + err = mp_read_unsigned_bin(&e, (byte*)in, (int)inlen); + + /* make up a key and export the public copy */ + if (err == MP_OKAY) { + ecc_key pubkey; + ecc_init(&pubkey); + for (;;) { + err = ecc_make_key_ex(rng, &pubkey, key->dp); + if (err != MP_OKAY) break; + + /* find r = x1 mod n */ + err = mp_mod(&pubkey.pubkey.x, &p, &r); + if (err != MP_OKAY) break; + + if (mp_iszero(&r) == MP_YES) + ecc_free(&pubkey); + else { + /* find s = (e + xr)/k */ + err = mp_invmod(&pubkey.k, &p, &pubkey.k); + if (err != MP_OKAY) break; + + err = mp_mulmod(&key->k, &r, &p, &s); /* s = xr */ + if (err != MP_OKAY) break; + + err = mp_add(&e, &s, &s); /* s = e + xr */ + if (err != MP_OKAY) break; + + err = mp_mod(&s, &p, &s); /* s = e + xr */ + if (err != MP_OKAY) break; + + err = mp_mulmod(&s, &pubkey.k, &p, &s); /* s = (e + xr)/k */ + if (err != MP_OKAY) break; + + ecc_free(&pubkey); + if (mp_iszero(&s) == MP_NO) + break; + } + } + ecc_free(&pubkey); + } + + /* store as SEQUENCE { r, s -- integer } */ + if (err == MP_OKAY) + err = StoreECC_DSA_Sig(out, outlen, &r, &s); + + mp_clear(&r); + mp_clear(&s); + mp_clear(&p); + mp_clear(&e); + + return err; +} + + +/** + Free an ECC key from memory + key The key you wish to free +*/ +void ecc_free(ecc_key* key) +{ + if (key == NULL) + return; + + mp_clear(&key->pubkey.x); + mp_clear(&key->pubkey.y); + mp_clear(&key->pubkey.z); + mp_clear(&key->k); +} + + +/* verify + * + * w = s^-1 mod n + * u1 = xw + * u2 = rw + * X = u1*G + u2*Q + * v = X_x1 mod n + * accept if v == r + */ + +/** + Verify an ECC signature + sig The signature to verify + siglen The length of the signature (octets) + hash The hash (message digest) that was signed + hashlen The length of the hash (octets) + stat Result of signature, 1==valid, 0==invalid + key The corresponding public ECC key + return MP_OKAY if successful (even if the signature is not valid) +*/ +int ecc_verify_hash(const byte* sig, word32 siglen, byte* hash, word32 hashlen, + int* stat, ecc_key* key) +{ + ecc_point *mG, *mQ; + mp_int r; + mp_int s; + mp_int v; + mp_int w; + mp_int u1; + mp_int u2; + mp_int e; + mp_int p; + mp_int m; + mp_digit mp; + int err; + + if (sig == NULL || hash == NULL || stat == NULL || key == NULL) + return ECC_BAD_ARG_E; + + /* default to invalid signature */ + *stat = 0; + + /* is the IDX valid ? */ + if (ecc_is_valid_idx(key->idx) != 1) { + return ECC_BAD_ARG_E; + } + + /* allocate ints */ + if ((err = mp_init_multi(&r, &s, &v, &w, &u1, &u2)) != MP_OKAY) { + return MEMORY_E; + } + + if ((err = mp_init_multi(&p, &e, &m, NULL, NULL, NULL)) != MP_OKAY) { + mp_clear(&r); + mp_clear(&s); + mp_clear(&v); + mp_clear(&w); + mp_clear(&u1); + mp_clear(&u2); + return MEMORY_E; + } + + /* allocate points */ + mG = ecc_new_point(); + mQ = ecc_new_point(); + if (mQ == NULL || mG == NULL) + err = MEMORY_E; + + if (err == MP_OKAY) + err = DecodeECC_DSA_Sig(sig, siglen, &r, &s); + + /* get the order */ + if (err == MP_OKAY) + err = mp_read_radix(&p, (char *)key->dp->order, 16); + + /* get the modulus */ + if (err == MP_OKAY) + err = mp_read_radix(&m, (char *)key->dp->prime, 16); + + /* check for zero */ + if (err == MP_OKAY) { + if (mp_iszero(&r) || mp_iszero(&s) || mp_cmp(&r, &p) != MP_LT || + mp_cmp(&s, &p) != MP_LT) + err = MP_ZERO_E; + } + /* read hash */ + if (err == MP_OKAY) + err = mp_read_unsigned_bin(&e, (byte*)hash, (int)hashlen); + + /* w = s^-1 mod n */ + if (err == MP_OKAY) + err = mp_invmod(&s, &p, &w); + + /* u1 = ew */ + if (err == MP_OKAY) + err = mp_mulmod(&e, &w, &p, &u1); + + /* u2 = rw */ + if (err == MP_OKAY) + err = mp_mulmod(&r, &w, &p, &u2); + + /* find mG and mQ */ + if (err == MP_OKAY) + err = mp_read_radix(&mG->x, (char *)key->dp->Gx, 16); + + if (err == MP_OKAY) + err = mp_read_radix(&mG->y, (char *)key->dp->Gy, 16); + if (err == MP_OKAY) + mp_set(&mG->z, 1); + + if (err == MP_OKAY) + err = mp_copy(&key->pubkey.x, &mQ->x); + if (err == MP_OKAY) + err = mp_copy(&key->pubkey.y, &mQ->y); + if (err == MP_OKAY) + err = mp_copy(&key->pubkey.z, &mQ->z); + +#ifndef ECC_SHAMIR + /* compute u1*mG + u2*mQ = mG */ + if (err == MP_OKAY) + err = ecc_mulmod(&u1, mG, mG, &m, 0); + if (err == MP_OKAY) + err = ecc_mulmod(&u2, mQ, mQ, &m, 0); + + /* find the montgomery mp */ + if (err == MP_OKAY) + err = mp_montgomery_setup(&m, &mp); + + /* add them */ + if (err == MP_OKAY) + err = ecc_projective_add_point(mQ, mG, mG, &m, &mp); + + /* reduce */ + if (err == MP_OKAY) + err = ecc_map(mG, &m, &mp); +#else + /* use Shamir's trick to compute u1*mG + u2*mQ using half the doubles */ + if (err == MP_OKAY) + err = ecc_mul2add(mG, &u1, mQ, &u2, mG, &m); +#endif /* ECC_SHAMIR */ + + /* v = X_x1 mod n */ + if (err == MP_OKAY) + err = mp_mod(&mG->x, &p, &v); + + /* does v == r */ + if (err == MP_OKAY) { + if (mp_cmp(&v, &r) == MP_EQ) + *stat = 1; + } + + ecc_del_point(mG); + ecc_del_point(mQ); + + mp_clear(&r); + mp_clear(&s); + mp_clear(&v); + mp_clear(&w); + mp_clear(&u1); + mp_clear(&u2); + mp_clear(&p); + mp_clear(&e); + mp_clear(&m); + + return err; +} + + +/* export public ECC key in ANSI X9.63 format */ +int ecc_export_x963(ecc_key* key, byte* out, word32* outLen) +{ + byte buf[ECC_BUFSIZE]; + word32 numlen; + + if (key == NULL || out == NULL || outLen == NULL) + return ECC_BAD_ARG_E; + + if (ecc_is_valid_idx(key->idx) == 0) { + return ECC_BAD_ARG_E; + } + numlen = key->dp->size; + + if (*outLen < (1 + 2*numlen)) { + *outLen = 1 + 2*numlen; + return BUFFER_E; + } + + /* store byte 0x04 */ + out[0] = 0x04; + + /* pad and store x */ + XMEMSET(buf, 0, sizeof(buf)); + mp_to_unsigned_bin(&key->pubkey.x, + buf + (numlen - mp_unsigned_bin_size(&key->pubkey.x))); + XMEMCPY(out+1, buf, numlen); + + /* pad and store y */ + XMEMSET(buf, 0, sizeof(buf)); + mp_to_unsigned_bin(&key->pubkey.y, + buf + (numlen - mp_unsigned_bin_size(&key->pubkey.y))); + XMEMCPY(out+1+numlen, buf, numlen); + + *outLen = 1 + 2*numlen; + + return 0; +} + + +/* import public ECC key in ANSI X9.63 format */ +int ecc_import_x963(const byte* in, word32 inLen, ecc_key* key) +{ + int x, err; + + + if (in == NULL || key == NULL) + return ECC_BAD_ARG_E; + + /* must be odd */ + if ((inLen & 1) == 0) { + return ECC_BAD_ARG_E; + } + + /* init key */ + if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, + NULL, NULL) != MP_OKAY) { + return MEMORY_E; + } + err = MP_OKAY; + + /* check for 4, 6 or 7 */ + if (in[0] != 4 && in[0] != 6 && in[0] != 7) { + err = ASN_PARSE_E; + } + + /* read data */ + if (err == MP_OKAY) + err = mp_read_unsigned_bin(&key->pubkey.x, (byte*)in+1, (inLen-1)>>1); + + if (err == MP_OKAY) + err = mp_read_unsigned_bin(&key->pubkey.y, (byte*)in+1+((inLen-1)>>1), + (inLen-1)>>1); + + if (err == MP_OKAY) + mp_set(&key->pubkey.z, 1); + + if (err == MP_OKAY) { + /* determine the idx */ + for (x = 0; ecc_sets[x].size != 0; x++) { + if ((unsigned)ecc_sets[x].size >= ((inLen-1)>>1)) { + break; + } + } + if (ecc_sets[x].size == 0) { + err = ASN_PARSE_E; + } else { + /* set the idx */ + key->idx = x; + key->dp = &ecc_sets[x]; + key->type = ECC_PUBLICKEY; + } + } + + if (err != MP_OKAY) { + mp_clear(&key->pubkey.x); + mp_clear(&key->pubkey.y); + mp_clear(&key->pubkey.z); + mp_clear(&key->k); + } + + return err; +} + + +/* ecc private key import, public key in ANSI X9.63 format, private raw */ +int ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub, + word32 pubSz, ecc_key* key) +{ + int ret = ecc_import_x963(pub, pubSz, key); + if (ret != 0) + return ret; + + key->type = ECC_PRIVATEKEY; + + return mp_read_unsigned_bin(&key->k, priv, privSz); +} + + +/* key size in octets */ +int ecc_size(ecc_key* key) +{ + if (key == NULL) return 0; + + return key->dp->size; +} + + +/* signature size in octets */ +int ecc_sig_size(ecc_key* key) +{ + int sz = ecc_size(key); + if (sz < 0) + return sz; + + return sz * 2 + SIG_HEADER_SZ; +} + +#endif /* HAVE_ECC */ diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index f3ed78a5f..885fed84b 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -285,6 +285,7 @@ CYASSL_API void CRYPTO_set_dynlock_lock_callback(void (*f)(int, CRYPTO_dynlock_value*, const char*, int)); CYASSL_API void CRYPTO_set_dynlock_destroy_callback(void (*f) (CRYPTO_dynlock_value*, const char*, int)); +CYASSL_API int CRYPTO_num_locks(void); CYASSL_API X509* X509_STORE_CTX_get_current_cert(X509_STORE_CTX*); CYASSL_API int X509_STORE_CTX_get_error(X509_STORE_CTX*); diff --git a/src/sniffer.c b/src/sniffer.c index 40891dfcf..286a9a051 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -481,6 +481,7 @@ typedef struct TcpPseudoHdr { /* Password Setting Callback */ static int SetPassword(char* passwd, int sz, int rw, void* userdata) { + (void)rw; XSTRNCPY(passwd, userdata, sz); return XSTRLEN(userdata); } @@ -692,7 +693,7 @@ static void TraceAddedData(int newBytes, int existingBytes) /* Show Stale Session */ -static void TraceStaleSession(SnifferSession* session) +static void TraceStaleSession(void) { if (TraceOn) { fprintf(TraceFile, "\tFound a stale session\n"); @@ -701,7 +702,7 @@ static void TraceStaleSession(SnifferSession* session) /* Show Finding Stale Sessions */ -static void TraceFindingStale() +static void TraceFindingStale(void) { if (TraceOn) { fprintf(TraceFile, "\tTrying to find Stale Sessions\n"); @@ -710,7 +711,7 @@ static void TraceFindingStale() /* Show Removed Session */ -static void TraceRemovedSession() +static void TraceRemovedSession(void) { if (TraceOn) { fprintf(TraceFile, "\tRemoved it\n"); @@ -763,7 +764,7 @@ static int IsPortRegistered(word32 port) sniffer = ServerList; while (sniffer) { - if (sniffer->port == port) { + if (sniffer->port == (int)port) { ret = 1; break; } @@ -978,7 +979,7 @@ static int ProcessClientKeyExchange(const byte* input, int* sslBytes, word32 idx = 0; RsaKey key; int ret; - + InitRsaKey(&key, 0); ret = RsaPrivateKeyDecode(session->context->ctx->privateKey.buffer, @@ -988,7 +989,12 @@ static int ProcessClientKeyExchange(const byte* input, int* sslBytes, if (IsTLS(session->sslServer)) input += 2; /* tls pre length */ - + + if (length > *sslBytes) { + SetError(PARTIAL_INPUT_STR, error, session, FATAL_ERROR_STATE); + FreeRsaKey(&key); + return -1; + } ret = RsaPrivateDecrypt(input, length, session->sslServer->arrays.preMasterSecret, SECRET_LEN, &key); @@ -1207,8 +1213,8 @@ static int ProcessClientHello(const byte* input, int* sslBytes, /* Process HandShake input */ -static int DoHandShake(const byte* input, int* sslBytes, IpInfo* ipInfo, - TcpInfo* tcpInfo, SnifferSession* session, char* error) +static int DoHandShake(const byte* input, int* sslBytes, + SnifferSession* session, char* error) { byte type; int size; @@ -1379,7 +1385,7 @@ static void RemoveSession(SnifferSession* session, IpInfo* ipInfo, /* Remove stale sessions from the Session Table, have a lock */ -static void RemoveStaleSessions() +static void RemoveStaleSessions(void) { word32 i; SnifferSession* session; @@ -1389,7 +1395,7 @@ static void RemoveStaleSessions() while (session) { SnifferSession* next = session->next; if (time(NULL) >= session->bornOn + SNIFFER_TIMEOUT) { - TraceStaleSession(session); + TraceStaleSession(); RemoveSession(session, NULL, NULL, i); } session = next; @@ -1507,6 +1513,7 @@ static int DoOldHello(SnifferSession* session, const byte* sslFrame, } +#if 0 /* Calculate the TCP checksum, see RFC 1071 */ /* return 0 for success, -1 on error */ /* can be called from decode() with @@ -1560,12 +1567,13 @@ int TcpChecksum(IpInfo* ipInfo, TcpInfo* tcpInfo, int dataLen, return 0; return -1; } +#endif /* Check IP and TCP headers, set payload */ /* returns 0 on success, -1 on error */ -int CheckHeaders(IpInfo* ipInfo, TcpInfo* tcpInfo, const byte* packet, - int length, const byte** sslFrame, int* sslBytes, char* error) +static int CheckHeaders(IpInfo* ipInfo, TcpInfo* tcpInfo, const byte* packet, + int length, const byte** sslFrame, int* sslBytes, char* error) { TraceHeader(); TracePacket(); @@ -1980,9 +1988,8 @@ static int HaveMoreInput(SnifferSession* session, const byte** sslFrame, /* Process Message(s) from sslFrame */ /* return Number of bytes on success, 0 for no data yet, and -1 on error */ -static int ProcessMessage(IpInfo* ipInfo, TcpInfo* tcpInfo,const byte* sslFrame, - SnifferSession* session, int sslBytes, byte* data, - const byte* end, char* error) +static int ProcessMessage(const byte* sslFrame, SnifferSession* session, + int sslBytes, byte* data, const byte* end,char* error) { const byte* sslBegin = sslFrame; const byte* tmp; @@ -2010,7 +2017,7 @@ doMessage: /* store partial if not there already or we advanced */ if (ssl->buffers.inputBuffer.length == 0 || sslBegin != sslFrame) { - if (sslBytes > ssl->buffers.inputBuffer.bufferSize) { + if (sslBytes > (int)ssl->buffers.inputBuffer.bufferSize) { SetError(BUFFER_ERROR_STR, error, session, FATAL_ERROR_STATE); return -1; } @@ -2036,8 +2043,7 @@ doMessage: switch ((enum ContentType)rh.type) { case handshake: Trace(GOT_HANDSHAKE_STR); - ret = DoHandShake(sslFrame, &sslBytes, ipInfo, tcpInfo, session, - error); + ret = DoHandShake(sslFrame, &sslBytes, session, error); if (ret != 0) { if (session->flags.fatalError == 0) SetError(BAD_HANDSHAKE_STR,error,session,FATAL_ERROR_STATE); @@ -2077,6 +2083,7 @@ doMessage: case alert: Trace(GOT_ALERT_STR); break; + case no_type: default: SetError(GOT_UNKNOWN_RECORD_STR, error, session, FATAL_ERROR_STATE); return -1; @@ -2156,8 +2163,7 @@ int ssl_DecodePacket(const byte* packet, int length, byte* data, char* error) if (ret == -1) return -1; else if (ret == 1) return 0; /* done for now */ - ret = ProcessMessage(&ipInfo, &tcpInfo, sslFrame, session, sslBytes, data, - end, error); + ret = ProcessMessage(sslFrame, session, sslBytes, data, end, error); CheckFinCapture(&ipInfo, &tcpInfo, session); return ret; } diff --git a/src/ssl.c b/src/ssl.c index 56e5450fb..63255d501 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -2295,6 +2295,8 @@ int CyaSSL_set_compression(SSL* ssl) long SSL_CTX_sess_set_cache_size(SSL_CTX* ctx, long sz) { /* cache size fixed at compile time in CyaSSL */ + (void)ctx; + (void)sz; return 0; } @@ -2310,6 +2312,7 @@ int CyaSSL_set_compression(SSL* ssl) int SSL_CTX_check_private_key(SSL_CTX* ctx) { /* TODO: check private against public for RSA match */ + (void)ctx; CYASSL_ENTER("SSL_CTX_check_private_key"); return SSL_SUCCESS; } @@ -2328,12 +2331,14 @@ int CyaSSL_set_compression(SSL* ssl) void SSL_CTX_set_client_CA_list(SSL_CTX* ctx, STACK_OF(X509_NAME)* names) { - + (void)ctx; + (void)names; } STACK_OF(X509_NAME)* SSL_load_client_CA_file(const char* fname) { + (void)fname; return 0; } @@ -2341,6 +2346,7 @@ int CyaSSL_set_compression(SSL* ssl) int SSL_CTX_set_default_verify_paths(SSL_CTX* ctx) { /* TODO:, not needed in goahead */ + (void)ctx; return SSL_NOT_IMPLEMENTED; } @@ -2379,12 +2385,15 @@ int CyaSSL_set_compression(SSL* ssl) void SSL_CTX_set_tmp_rsa_callback(SSL_CTX* ctx, RSA*(*f)(SSL*, int, int)) { /* CyaSSL verifies all these internally */ + (void)ctx; + (void)f; } void SSL_set_shutdown(SSL* ssl, int opt) { - + (void)ssl; + (void)opt; } @@ -2392,6 +2401,7 @@ int CyaSSL_set_compression(SSL* ssl) { /* goahead calls with 0, do nothing */ CYASSL_ENTER("SSL_CTX_set_options"); + (void)ctx; return opt; } @@ -2423,6 +2433,10 @@ int CyaSSL_set_compression(SSL* ssl) { /* no tmp key needed, actual generation not supported */ CYASSL_ENTER("RSA_generate_key"); + (void)len; + (void)bits; + (void)f; + (void)data; return 0; } @@ -2468,18 +2482,21 @@ int CyaSSL_set_compression(SSL* ssl) X509* X509_STORE_CTX_get_current_cert(X509_STORE_CTX* ctx) { + (void)ctx; return 0; } int X509_STORE_CTX_get_error(X509_STORE_CTX* ctx) { + (void)ctx; return 0; } int X509_STORE_CTX_get_error_depth(X509_STORE_CTX* ctx) { + (void)ctx; return 0; } @@ -2499,6 +2516,7 @@ int CyaSSL_set_compression(SSL* ssl) { /* CyaSSL has internal buffer, compatibility only */ CYASSL_ENTER("BIO_set_write_buffer_size"); + (void)bio; return size; } @@ -2677,6 +2695,7 @@ int CyaSSL_set_compression(SSL* ssl) { /* for CyaSSL no flushing needed */ CYASSL_ENTER("BIO_flush"); + (void)bio; return 1; } @@ -2706,12 +2725,12 @@ int CyaSSL_set_compression(SSL* ssl) void CRYPTO_set_locking_callback(void (*f)(int, int, const char*, int)) { - + (void)f; } void CRYPTO_set_id_callback(unsigned long (*f)(void)) { - + (void)f; } unsigned long ERR_get_error(void) @@ -2821,6 +2840,7 @@ int CyaSSL_set_compression(SSL* ssl) const char* SSLeay_version(int type) { static const char* version = "SSLeay CyaSSL compatibility"; + (void)type; return version; } @@ -2912,6 +2932,7 @@ int CyaSSL_set_compression(SSL* ssl) void EVP_MD_CTX_init(EVP_MD_CTX* ctx) { + (void)ctx; /* do nothing */ } @@ -2919,6 +2940,7 @@ int CyaSSL_set_compression(SSL* ssl) int EVP_MD_CTX_cleanup(EVP_MD_CTX* ctx) { CYASSL_ENTER("EVP_MD_CTX_cleanup"); + (void)ctx; return 0; } @@ -3081,6 +3103,7 @@ int CyaSSL_set_compression(SSL* ssl) void ERR_remove_state(unsigned long state) { /* TODO: GetErrors().Remove(); */ + (void)state; } @@ -3111,6 +3134,7 @@ int CyaSSL_set_compression(SSL* ssl) long SSL_CTX_get_mode(SSL_CTX* ctx) { /* TODO: */ + (void)ctx; return 0; } @@ -3118,6 +3142,8 @@ int CyaSSL_set_compression(SSL* ssl) void SSL_CTX_set_default_read_ahead(SSL_CTX* ctx, int m) { /* TODO: maybe? */ + (void)ctx; + (void)m; } @@ -3126,6 +3152,9 @@ int CyaSSL_set_compression(SSL* ssl) unsigned int sid_ctx_len) { /* No application specific context needed for cyaSSL */ + (void)ctx; + (void)sid_ctx; + (void)sid_ctx_len; return SSL_SUCCESS; } @@ -3133,6 +3162,7 @@ int CyaSSL_set_compression(SSL* ssl) long SSL_CTX_sess_get_cache_size(SSL_CTX* ctx) { /* TODO: maybe? */ + (void)ctx; return (~0); } @@ -3140,6 +3170,10 @@ int CyaSSL_set_compression(SSL* ssl) const char** data, int *flags) { /* Not implemented */ + (void)file; + (void)line; + (void)data; + (void)flags; return 0; } @@ -3157,12 +3191,16 @@ int CyaSSL_set_compression(SSL* ssl) int SSL_set_ex_data(SSL* ssl, int idx, void* data) { + (void)ssl; + (void)idx; + (void)data; return 0; } int SSL_get_shutdown(const SSL* ssl) { + (void)ssl; return 0; } @@ -3170,12 +3208,16 @@ int CyaSSL_set_compression(SSL* ssl) int SSL_set_session_id_context(SSL* ssl, const unsigned char* id, unsigned int len) { + (void)ssl; + (void)id; + (void)len; return 0; } void SSL_set_connect_state(SSL* ssl) { + (void)ssl; /* client by default */ } @@ -3188,7 +3230,7 @@ int CyaSSL_set_compression(SSL* ssl) void SSL_SESSION_free(SSL_SESSION* session) { - + (void)session; } @@ -3297,31 +3339,40 @@ int CyaSSL_set_compression(SSL* ssl) char* SSL_CIPHER_description(SSL_CIPHER* cipher, char* buffer, int len) { + (void)cipher; + (void)buffer; + (void)len; return 0; } SSL_SESSION* SSL_get1_session(SSL* ssl) /* what's ref count */ { + (void)ssl; return 0; } void X509_free(X509* buf) { - + (void)buf; } void OPENSSL_free(void* buf) { - + (void)buf; } int OCSP_parse_url(char* url, char** host, char** port, char** path, int* ssl) { + (void)url; + (void)host; + (void)port; + (void)path; + (void)ssl; return 0; } @@ -3369,12 +3420,14 @@ int CyaSSL_set_compression(SSL* ssl) BIO* BIO_pop(BIO* top) { + (void)top; return 0; } int BIO_pending(BIO* bio) { + (void)bio; return 0; } @@ -3394,7 +3447,8 @@ int CyaSSL_set_compression(SSL* ssl) void BIO_set_flags(BIO* bio, int flags) { - + (void)bio; + (void)flags; } @@ -3407,18 +3461,22 @@ int CyaSSL_set_compression(SSL* ssl) const char* RAND_file_name(char* fname, unsigned long len) { + (void)fname; + (void)len; return 0; } int RAND_write_file(const char* fname) { + (void)fname; return 0; } int RAND_load_file(const char* fname, long len) { + (void)fname; /* CTaoCrypt provides enough entropy internally or will report error */ if (len == -1) return 1024; @@ -3429,6 +3487,7 @@ int CyaSSL_set_compression(SSL* ssl) int RAND_egd(const char* path) { + (void)path; return 0; } @@ -3448,6 +3507,8 @@ int CyaSSL_set_compression(SSL* ssl) int SSL_COMP_add_compression_method(int method, void* data) { + (void)method; + (void)data; return 0; } @@ -3456,6 +3517,11 @@ int CyaSSL_set_compression(SSL* ssl) int SSL_get_ex_new_index(long idx, void* data, void* cb1, void* cb2, void* cb3) { + (void)idx; + (void)data; + (void)cb1; + (void)cb2; + (void)cb3; return 0; } @@ -3463,27 +3529,28 @@ int CyaSSL_set_compression(SSL* ssl) void CRYPTO_set_dynlock_create_callback(CRYPTO_dynlock_value* (*f)( const char*, int)) { - + (void)f; } void CRYPTO_set_dynlock_lock_callback(void (*f)(int, CRYPTO_dynlock_value*, const char*, int)) { - + (void)f; } void CRYPTO_set_dynlock_destroy_callback(void (*f)(CRYPTO_dynlock_value*, const char*, int)) { - + (void)f; } const char* X509_verify_cert_error_string(long err) { + (void)err; return 0; } @@ -3491,12 +3558,18 @@ int CyaSSL_set_compression(SSL* ssl) int X509_LOOKUP_add_dir(X509_LOOKUP* lookup, const char* dir, long len) { + (void)lookup; + (void)dir; + (void)len; return 0; } int X509_LOOKUP_load_file(X509_LOOKUP* lookup, const char* file, long len) { + (void)lookup; + (void)file; + (void)len; return 0; } @@ -3516,6 +3589,8 @@ int CyaSSL_set_compression(SSL* ssl) X509_LOOKUP* X509_STORE_add_lookup(X509_STORE* store, X509_LOOKUP_METHOD* m) { + (void)store; + (void)m; return 0; } @@ -3529,6 +3604,10 @@ int CyaSSL_set_compression(SSL* ssl) int X509_STORE_get_by_subject(X509_STORE_CTX* ctx, int idx, X509_NAME* name, X509_OBJECT* obj) { + (void)ctx; + (void)idx; + (void)name; + (void)obj; return 0; } @@ -3536,25 +3615,31 @@ int CyaSSL_set_compression(SSL* ssl) int X509_STORE_CTX_init(X509_STORE_CTX* ctx, X509_STORE* store, X509* x509, STACK_OF(X509)* sk) { + (void)ctx; + (void)store; + (void)x509; + (void)sk; return 0; } void X509_STORE_CTX_cleanup(X509_STORE_CTX* ctx) { - + (void)ctx; } ASN1_TIME* X509_CRL_get_lastUpdate(X509_CRL* crl) { + (void)crl; return 0; } ASN1_TIME* X509_CRL_get_nextUpdate(X509_CRL* crl) { + (void)crl; return 0; } @@ -3562,42 +3647,48 @@ int CyaSSL_set_compression(SSL* ssl) EVP_PKEY* X509_get_pubkey(X509* x509) { + (void)x509; return 0; } int X509_CRL_verify(X509_CRL* crl, EVP_PKEY* key) { + (void)crl; + (void)key; return 0; } void X509_STORE_CTX_set_error(X509_STORE_CTX* ctx, int err) { - + (void)ctx; + (void)err; } void X509_OBJECT_free_contents(X509_OBJECT* obj) { - + (void)obj; } void EVP_PKEY_free(EVP_PKEY* key) { - + (void)key; } int X509_cmp_current_time(const ASN1_TIME* time) { + (void)time; return 0; } int sk_X509_REVOKED_num(X509_REVOKED* revoked) { + (void)revoked; return 0; } @@ -3605,12 +3696,15 @@ int CyaSSL_set_compression(SSL* ssl) X509_REVOKED* X509_CRL_get_REVOKED(X509_CRL* crl) { + (void)crl; return 0; } X509_REVOKED* sk_X509_REVOKED_value(X509_REVOKED* revoked, int value) { + (void)revoked; + (void)value; return 0; } @@ -3618,6 +3712,7 @@ int CyaSSL_set_compression(SSL* ssl) ASN1_INTEGER* X509_get_serialNumber(X509* x509) { + (void)x509; return 0; } @@ -3625,6 +3720,8 @@ int CyaSSL_set_compression(SSL* ssl) int ASN1_TIME_print(BIO* bio, const ASN1_TIME* time) { + (void)bio; + (void)time; return 0; } @@ -3632,12 +3729,15 @@ int CyaSSL_set_compression(SSL* ssl) int ASN1_INTEGER_cmp(const ASN1_INTEGER* a, const ASN1_INTEGER* b) { + (void)a; + (void)b; return 0; } long ASN1_INTEGER_get(const ASN1_INTEGER* i) { + (void)i; return 0; } @@ -3645,6 +3745,8 @@ int CyaSSL_set_compression(SSL* ssl) void* X509_STORE_CTX_get_ex_data(X509_STORE_CTX* ctx, int idx) { + (void)ctx; + (void)idx; return 0; } @@ -3657,19 +3759,24 @@ int CyaSSL_set_compression(SSL* ssl) void* SSL_get_ex_data(const SSL* ssl, int idx) { + (void)ssl; + (void)idx; return 0; } long SSL_CTX_set_timeout(SSL_CTX* ctx, long to) { + (void)ctx; + (void)to; return 0; } - void SSL_CTX_set_info_callback(SSL_CTX* ctx, void (*f)()) + void SSL_CTX_set_info_callback(SSL_CTX* ctx, void (*f)(void)) { - + (void)ctx; + (void)f; } @@ -3681,24 +3788,28 @@ int CyaSSL_set_compression(SSL* ssl) int ERR_GET_REASON(int err) { + (void)err; return 0; } char* SSL_alert_type_string_long(int alert) { + (void)alert; return 0; } char* SSL_alert_desc_string_long(int alert) { + (void)alert; return 0; } char* SSL_state_string_long(SSL* ssl) { + (void)ssl; return 0; } @@ -3706,123 +3817,153 @@ int CyaSSL_set_compression(SSL* ssl) void RSA_free(RSA* rsa) { - + (void)rsa; } int PEM_def_callback(char* name, int num, int w, void* key) { + (void)name; + (void)num; + (void)w; + (void)key; return 0; } long SSL_CTX_sess_accept(SSL_CTX* ctx) { + (void)ctx; return 0; } long SSL_CTX_sess_connect(SSL_CTX* ctx) { + (void)ctx; return 0; } long SSL_CTX_sess_accept_good(SSL_CTX* ctx) { + (void)ctx; return 0; } long SSL_CTX_sess_connect_good(SSL_CTX* ctx) { + (void)ctx; return 0; } long SSL_CTX_sess_accept_renegotiate(SSL_CTX* ctx) { + (void)ctx; return 0; } long SSL_CTX_sess_connect_renegotiate(SSL_CTX* ctx) { + (void)ctx; return 0; } long SSL_CTX_sess_hits(SSL_CTX* ctx) { + (void)ctx; return 0; } long SSL_CTX_sess_cb_hits(SSL_CTX* ctx) { + (void)ctx; return 0; } long SSL_CTX_sess_cache_full(SSL_CTX* ctx) { + (void)ctx; return 0; } long SSL_CTX_sess_misses(SSL_CTX* ctx) { + (void)ctx; return 0; } long SSL_CTX_sess_timeouts(SSL_CTX* ctx) { + (void)ctx; return 0; } long SSL_CTX_sess_number(SSL_CTX* ctx) { + (void)ctx; return 0; } void DES_set_key_unchecked(const_DES_cblock* des, DES_key_schedule* key) { + (void)des; + (void)key; } void DES_set_odd_parity(DES_cblock* des) { + (void)des; } void DES_ecb_encrypt(DES_cblock* desa, DES_cblock* desb, DES_key_schedule* key, int len) { + (void)desa; + (void)desb; + (void)key; + (void)len; } int BIO_printf(BIO* bio, const char* format, ...) { + (void)bio; + (void)format; return 0; } int ASN1_UTCTIME_print(BIO* bio, const ASN1_UTCTIME* a) { + (void)bio; + (void)a; return 0; } int sk_num(X509_REVOKED* rev) { + (void)rev; return 0; } void* sk_value(X509_REVOKED* rev, int i) { + (void)rev; + (void)i; return 0; } @@ -3830,12 +3971,17 @@ int CyaSSL_set_compression(SSL* ssl) /* stunnel 4.28 needs */ void* SSL_CTX_get_ex_data(const SSL_CTX* ctx, int d) { + (void)ctx; + (void)d; return 0; } int SSL_CTX_set_ex_data(SSL_CTX* ctx, int d, void* p) { + (void)ctx; + (void)d; + (void)p; return SSL_SUCCESS; } @@ -3843,25 +3989,30 @@ int CyaSSL_set_compression(SSL* ssl) void SSL_CTX_sess_set_get_cb(SSL_CTX* ctx, SSL_SESSION*(*f)(SSL*, unsigned char*, int, int*)) { - + (void)ctx; + (void)f; } void SSL_CTX_sess_set_new_cb(SSL_CTX* ctx, int (*f)(SSL*, SSL_SESSION*)) { - + (void)ctx; + (void)f; } void SSL_CTX_sess_set_remove_cb(SSL_CTX* ctx, void (*f)(SSL_CTX*, SSL_SESSION*)) { - + (void)ctx; + (void)f; } int i2d_SSL_SESSION(SSL_SESSION* sess, unsigned char** p) { + (void)sess; + (void)p; return sizeof(SSL_SESSION); } @@ -3869,6 +4020,8 @@ int CyaSSL_set_compression(SSL* ssl) SSL_SESSION* d2i_SSL_SESSION(SSL_SESSION** sess, const unsigned char** p, long i) { + (void)p; + (void)i; if (sess) return *sess; return NULL; @@ -3891,6 +4044,11 @@ int CyaSSL_set_compression(SSL* ssl) int SSL_CTX_get_ex_new_index(long idx, void* arg, void* a, void* b, void* c) { + (void)idx; + (void)arg; + (void)a; + (void)b; + (void)c; return 0; }