From sreeharsha at totakura.in Fri Jun 6 10:30:29 2014 From: sreeharsha at totakura.in (Sree Harsha Totakura) Date: Fri, 06 Jun 2014 10:30:29 +0200 Subject: Comparing EC MPI points In-Reply-To: <539172A3.103@totakura.in> References: <539172A3.103@totakura.in> Message-ID: <53917C25.4020203@totakura.in> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 06/06/2014 09:49 AM, Sree Harsha Totakura wrote: > If not, are there any alternatives for compare them with the current code > base? I found a way: compare the points' coordinates after retrieving them with gcry_mpi_point_get(). Sree -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 Comment: Using GnuPG with Icedove - http://www.enigmail.net/ iQEcBAEBAgAGBQJTkXwlAAoJECthXLMALpxG+OYH/1GWchxQNGSPMCxn/GKwGREa DDGa1xotq8G/OXCwXFErFE1/Vp9Z1fOoEqG5IDhco8JplS7mUrcla1lW5wPd0BUd 27Pt0DXW3iQjfcDVGClTuiuMS8lmd/ZEN6CLf2d7SgOgLm81imjr2KexrpkGcEw1 4+B4OqjKHqPujxlycj04iXRm6+IoLwMDrlNT2EAZyPb7ZdRuk9nHcuQAxti0HKRq ZVwFpeRIi3G4KcKZepHA6shGAiDmphRN2AySlsFFT2x/DhwTgD1IB73OIkp3Wduw 5SAuiIOo6tvDWYJxXynMy3wfQh0OFDX3InIt+XlCCIUgJXmW6rszfLotuiz2FNY= =E8r6 -----END PGP SIGNATURE----- From sreeharsha at totakura.in Fri Jun 6 09:49:55 2014 From: sreeharsha at totakura.in (Sree Harsha Totakura) Date: Fri, 06 Jun 2014 09:49:55 +0200 Subject: Comparing EC MPI points Message-ID: <539172A3.103@totakura.in> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi, Are there any functions similar to gcry_mpi_cmp* for comparing EC points? If not, are there any alternatives for compare them with the current code base? (I am using the 1.6.1 git version) Sree -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 Comment: Using GnuPG with Icedove - http://www.enigmail.net/ iQEcBAEBAgAGBQJTkXKfAAoJECthXLMALpxGV58H/itcJhyN89hqPO5KOz3ewU9w 3BAmNuGwTalmTkL/TsamUEOfPsJG/zy1A70oOTx469EJs1cn+5/3d/fpI/1Xfixe /Rhxy/fcnKmDN51mPqM/n5uZzKjl5f3HcWcBOOzsnqhmtEXXqc5Ah278wNyrxkHc 2LoDhd2MQ7+aTODsx+tpdWV+Fq/hdZPVxYYafs61vwibWqbFJ42Gn7Swq5FrgPC2 xoFR3RtL81kNAwehWUuw/gi/JsHAzUlyaWkqAEBE4t7HjB6gReYrtBSKrZJIs6l6 cBi3Pg37NYm+c8EbHHl79z4qg5J8KRykFVxE8CnMWR3Mq99FsrFfJCjUKTUnmMo= =sn8r -----END PGP SIGNATURE----- From dbaryshkov at gmail.com Fri Jun 6 20:48:36 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Fri, 6 Jun 2014 22:48:36 +0400 Subject: [PATCH 10/10] gostr3411_94: rewrite to use u32 mathematic In-Reply-To: <1402080516-8098-1-git-send-email-dbaryshkov@gmail.com> References: <1402080516-8098-1-git-send-email-dbaryshkov@gmail.com> Message-ID: <1402080516-8098-11-git-send-email-dbaryshkov@gmail.com> * cipher/gost28147.c (_gcry_gost_enc_data): New. * cipher/gostr3411-94.c: Rewrite implementation to use u32 mathematic internally. * cipher/gost28147.c (_gcry_gost_enc_one): Remove. -- On my box (Core2 Duo, i386) this highly improves GOST R 34.11-94 speed. Before: GOSTR3411_94 | 55.04 ns/B 17.33 MiB/s - c/B After: GOSTR3411_94 | 36.70 ns/B 25.99 MiB/s - c/B Signed-off-by: Dmitry Eremin-Solenikov --- cipher/gost.h | 4 +- cipher/gost28147.c | 36 ++++++--- cipher/gostr3411-94.c | 202 ++++++++++++++++++++++++++++---------------------- 3 files changed, 139 insertions(+), 103 deletions(-) diff --git a/cipher/gost.h b/cipher/gost.h index caaf34b..025119c 100644 --- a/cipher/gost.h +++ b/cipher/gost.h @@ -26,7 +26,7 @@ typedef struct { } GOST28147_context; /* This is a simple interface that will be used by GOST R 34.11-94 */ -extern unsigned int _gcry_gost_enc_one (GOST28147_context *c, const byte *key, - byte *out, byte *in, int cryptopro); +unsigned int _gcry_gost_enc_data (GOST28147_context *c, const u32 *key, + u32 *o1, u32 *o2, u32 n1, u32 n2, int cryptopro); #endif diff --git a/cipher/gost28147.c b/cipher/gost28147.c index 0841722..5db9f0b 100644 --- a/cipher/gost28147.c +++ b/cipher/gost28147.c @@ -69,13 +69,9 @@ gost_val (GOST28147_context *ctx, u32 cm1, int subkey) } static unsigned int -gost_encrypt_block (void *c, byte *outbuf, const byte *inbuf) +_gost_encrypt_data (void *c, u32 *o1, u32 *o2, u32 n1, u32 n2) { GOST28147_context *ctx = c; - u32 n1, n2; - - n1 = buf_get_le32 (inbuf); - n2 = buf_get_le32 (inbuf+4); n2 ^= gost_val (ctx, n1, 0); n1 ^= gost_val (ctx, n2, 1); n2 ^= gost_val (ctx, n1, 2); n1 ^= gost_val (ctx, n2, 3); @@ -97,23 +93,41 @@ gost_encrypt_block (void *c, byte *outbuf, const byte *inbuf) n2 ^= gost_val (ctx, n1, 3); n1 ^= gost_val (ctx, n2, 2); n2 ^= gost_val (ctx, n1, 1); n1 ^= gost_val (ctx, n2, 0); - buf_put_le32 (outbuf+0, n2); - buf_put_le32 (outbuf+4, n1); + *o1 = n2; + *o2 = n1; return /* burn_stack */ 4*sizeof(void*) /* func call */ + 3*sizeof(void*) /* stack */ + 4*sizeof(void*) /* gost_val call */; } -unsigned int _gcry_gost_enc_one (GOST28147_context *c, const byte *key, - byte *out, byte *in, int cryptopro) +static unsigned int +gost_encrypt_block (void *c, byte *outbuf, const byte *inbuf) +{ + GOST28147_context *ctx = c; + u32 n1, n2; + unsigned int burn; + + n1 = buf_get_le32 (inbuf); + n2 = buf_get_le32 (inbuf+4); + + burn = _gost_encrypt_data(ctx, &n1, &n2, n1, n2); + + buf_put_le32 (outbuf+0, n1); + buf_put_le32 (outbuf+4, n2); + + return /* burn_stack */ burn + 6*sizeof(void*) /* func call */; +} + +unsigned int _gcry_gost_enc_data (GOST28147_context *c, const u32 *key, + u32 *o1, u32 *o2, u32 n1, u32 n2, int cryptopro) { if (cryptopro) c->sbox = sbox_CryptoPro_3411; else c->sbox = sbox_test_3411; - gost_setkey (c, key, 32); - return gost_encrypt_block (c, out, in) + 5 * sizeof(void *); + memcpy (c->key, key, 8*4); + return _gost_encrypt_data (c, o1, o2, n1, n2) + 7 * sizeof(void *); } static unsigned int diff --git a/cipher/gostr3411-94.c b/cipher/gostr3411-94.c index 9d065fb..91e5b4c 100644 --- a/cipher/gostr3411-94.c +++ b/cipher/gostr3411-94.c @@ -25,6 +25,7 @@ #include "g10lib.h" #include "bithelp.h" +#include "bufhelp.h" #include "cipher.h" #include "hash-common.h" @@ -35,8 +36,11 @@ typedef struct { gcry_md_block_ctx_t bctx; GOST28147_context hd; - byte h[32]; - byte sigma[32]; + union { + u32 h[8]; + byte result[32]; + }; + u32 sigma[8]; u32 len; int cryptopro; } GOSTR3411_CONTEXT; @@ -71,102 +75,122 @@ gost3411_cp_init (void *context, unsigned int flags) } static void -do_p (unsigned char *p, unsigned char *u, unsigned char *v) +do_p (u32 *p, u32 *u, u32 *v) { - int i, k; + int k; + u32 t[8]; + for (k = 0; k < 8; k++) + t[k] = u[k] ^ v[k]; + + for (k = 0; k < 4; k++) { - for (i = 0; i < 4; i++) - { - p[i + 4 * k] = u[8 * i + k] ^ v[8 * i + k]; - } + p[k+0] = ((t[0] >> (8*k)) & 0xff) << 0 | + ((t[2] >> (8*k)) & 0xff) << 8 | + ((t[4] >> (8*k)) & 0xff) << 16 | + ((t[6] >> (8*k)) & 0xff) << 24; + p[k+4] = ((t[1] >> (8*k)) & 0xff) << 0 | + ((t[3] >> (8*k)) & 0xff) << 8 | + ((t[5] >> (8*k)) & 0xff) << 16 | + ((t[7] >> (8*k)) & 0xff) << 24; } } static void -do_a (unsigned char *u) +do_a (u32 *u) { - unsigned char temp[8]; + u32 t[2]; int i; - memcpy (temp, u, 8); - memmove (u, u+8, 24); - for (i = 0; i < 8; i++) - { - u[24 + i] = u[i] ^ temp[i]; - } + memcpy(t, u, 2*4); + for (i = 0; i < 6; i++) + u[i] = u[i+2]; + u[6] = u[0] ^ t[0]; + u[7] = u[1] ^ t[1]; } /* apply do_a twice: 1 2 3 4 -> 3 4 1^2 2^3 */ static void -do_a2 (unsigned char *u) +do_a2 (u32 *u) { - unsigned char temp[16]; + u32 t[4]; int i; - memcpy (temp, u, 16); - memcpy (u, u + 16, 16); - for (i = 0; i < 8; i++) + memcpy (t, u, 16); + memcpy (u, u + 4, 16); + for (i = 0; i < 2; i++) { - u[16 + i] = temp[i] ^ temp[8 + i]; - u[24 + i] = u[i] ^ temp[8 + i]; + u[4+i] = t[i] ^ t[i + 2]; + u[6+i] = u[i] ^ t[i + 2]; } } static void -do_apply_c2 (unsigned char *u) +do_apply_c2 (u32 *u) { - u[ 1] ^= 0xff; - u[ 3] ^= 0xff; - u[ 5] ^= 0xff; - u[ 7] ^= 0xff; - - u[ 8] ^= 0xff; - u[10] ^= 0xff; - u[12] ^= 0xff; - u[14] ^= 0xff; - - u[17] ^= 0xff; - u[18] ^= 0xff; - u[20] ^= 0xff; - u[23] ^= 0xff; - - u[24] ^= 0xff; - u[28] ^= 0xff; - u[29] ^= 0xff; - u[31] ^= 0xff; + u[ 0] ^= 0xff00ff00; + u[ 1] ^= 0xff00ff00; + u[ 2] ^= 0x00ff00ff; + u[ 3] ^= 0x00ff00ff; + u[ 4] ^= 0x00ffff00; + u[ 5] ^= 0xff0000ff; + u[ 6] ^= 0x000000ff; + u[ 7] ^= 0xff00ffff; } -#define do_phi_step(e, i) \ - e[(0 + 2*i) % 32] ^= e[(2 + 2*i) % 32] ^ e[(4 + 2*i) % 32] ^ e[(6 + 2*i) % 32] ^ e[(24 + 2*i) % 32] ^ e[(30 + 2*i) % 32]; \ - e[(1 + 2*i) % 32] ^= e[(3 + 2*i) % 32] ^ e[(5 + 2*i) % 32] ^ e[(7 + 2*i) % 32] ^ e[(25 + 2*i) % 32] ^ e[(31 + 2*i) % 32]; +#define do_chi_step12(e) \ + e[6] ^= ((e[6] >> 16) ^ e[7] ^ (e[7] >> 16) ^ e[4] ^ (e[5] >>16)) & 0xffff; + +#define do_chi_step13(e) \ + e[6] ^= ((e[7] ^ (e[7] >> 16) ^ e[0] ^ (e[4] >> 16) ^ e[6]) & 0xffff) << 16; + +#define do_chi_doublestep(e, i) \ + e[i] ^= (e[i] >> 16) ^ (e[(i+1)%8] << 16) ^ e[(i+1)%8] ^ (e[(i+1)%8] >> 16) ^ (e[(i+2)%8] << 16) ^ e[(i+6)%8] ^ (e[(i+7)%8] >> 16); \ + e[i] ^= (e[i] << 16); static void -do_phi_submix (unsigned char *e, unsigned char *x, int round) +do_chi_submix12 (u32 *e, u32 *x) { - int i; - round *= 2; - for (i = 0; i < 32; i++) - { - e[(i + round) % 32] ^= x[i]; - } + e[6] ^= x[0]; + e[7] ^= x[1]; + e[0] ^= x[2]; + e[1] ^= x[3]; + e[2] ^= x[4]; + e[3] ^= x[5]; + e[4] ^= x[6]; + e[5] ^= x[7]; +} + +static void +do_chi_submix13 (u32 *e, u32 *x) +{ + e[6] ^= (x[0] << 16) | (x[7] >> 16); + e[7] ^= (x[1] << 16) | (x[0] >> 16); + e[0] ^= (x[2] << 16) | (x[1] >> 16); + e[1] ^= (x[3] << 16) | (x[2] >> 16); + e[2] ^= (x[4] << 16) | (x[3] >> 16); + e[3] ^= (x[5] << 16) | (x[4] >> 16); + e[4] ^= (x[6] << 16) | (x[5] >> 16); + e[5] ^= (x[7] << 16) | (x[6] >> 16); } static void -do_add (unsigned char *s, unsigned char *a) +do_add (u32 *s, u32 *a) { - unsigned temp = 0; + u32 carry = 0; int i; - for (i = 0; i < 32; i++) + for (i = 0; i < 8; i++) { - temp = s[i] + a[i] + (temp >> 8); - s[i] = temp & 0xff; + u32 op = carry + a[i]; + s[i] += op; + carry = (a[i] > op) || (op > s[i]); } } static unsigned int -do_hash_step (GOSTR3411_CONTEXT *hd, unsigned char *h, unsigned char *m) +do_hash_step (GOSTR3411_CONTEXT *hd, u32 *h, u32 *m) { - unsigned char u[32], v[32], s[32]; - unsigned char k[32]; + u32 u[8], v[8]; + u32 s[8]; + u32 k[8]; unsigned int burn; int i; @@ -176,7 +200,7 @@ do_hash_step (GOSTR3411_CONTEXT *hd, unsigned char *h, unsigned char *m) for (i = 0; i < 4; i++) { do_p (k, u, v); - burn = _gcry_gost_enc_one (&hd->hd, k, s + i*8, h + i*8, hd->cryptopro); + burn = _gcry_gost_enc_data (&hd->hd, k, &s[2*i], &s[2*i+1], h[2*i], h[2*i+1], hd->cryptopro); do_a (u); if (i == 1) @@ -186,33 +210,26 @@ do_hash_step (GOSTR3411_CONTEXT *hd, unsigned char *h, unsigned char *m) for (i = 0; i < 5; i++) { - do_phi_step (s, 0); - do_phi_step (s, 1); - do_phi_step (s, 2); - do_phi_step (s, 3); - do_phi_step (s, 4); - do_phi_step (s, 5); - do_phi_step (s, 6); - do_phi_step (s, 7); - do_phi_step (s, 8); - do_phi_step (s, 9); + do_chi_doublestep (s, 0); + do_chi_doublestep (s, 1); + do_chi_doublestep (s, 2); + do_chi_doublestep (s, 3); + do_chi_doublestep (s, 4); /* That is in total 12 + 1 + 61 = 74 = 16 * 4 + 10 rounds */ if (i == 4) break; - do_phi_step (s, 10); - do_phi_step (s, 11); + do_chi_doublestep (s, 5); if (i == 0) - do_phi_submix(s, m, 12); - do_phi_step (s, 12); + do_chi_submix12(s, m); + do_chi_step12 (s); if (i == 0) - do_phi_submix(s, h, 13); - do_phi_step (s, 13); - do_phi_step (s, 14); - do_phi_step (s, 15); + do_chi_submix13(s, h); + do_chi_step13 (s); + do_chi_doublestep (s, 7); } - memcpy (h, s+20, 12); - memcpy (h+12, s, 20); + memcpy (h, s+5, 12); + memcpy (h+3, s, 20); return /* burn_stack */ 4 * sizeof(void*) /* func call (ret addr + args) */ + 4 * 32 + 2 * sizeof(int) /* stack */ + @@ -221,15 +238,16 @@ do_hash_step (GOSTR3411_CONTEXT *hd, unsigned char *h, unsigned char *m) 16 + sizeof(int) /* do_a2 stack */ ); } - static unsigned int transform_blk (void *ctx, const unsigned char *data) { GOSTR3411_CONTEXT *hd = ctx; - byte m[32]; + u32 m[8]; unsigned int burn; + int i; - memcpy (m, data, 32); + for (i = 0; i < 8; i++) + m[i] = buf_get_le32(data + i*4); burn = do_hash_step (hd, hd->h, m); do_add (hd->sigma, m); @@ -263,9 +281,9 @@ gost3411_final (void *context) { GOSTR3411_CONTEXT *hd = context; size_t padlen = 0; - byte l[32]; + u32 l[8]; int i; - u32 nblocks; + MD_NBLOCKS_TYPE nblocks; if (hd->bctx.count > 0) { @@ -286,15 +304,19 @@ gost3411_final (void *context) nblocks --; l[0] = 256 - padlen * 8; } + l[0] |= nblocks << 8; + nblocks >>= 24; for (i = 1; i < 32 && nblocks != 0; i++) { - l[i] = nblocks % 256; - nblocks /= 256; + l[i] = nblocks; + nblocks >>= 24; } do_hash_step (hd, hd->h, l); do_hash_step (hd, hd->h, hd->sigma); + for (i = 0; i < 8; i++) + hd->h[i] = le_bswap32(hd->h[i]); } static byte * @@ -302,7 +324,7 @@ gost3411_read (void *context) { GOSTR3411_CONTEXT *hd = context; - return hd->h; + return hd->result; } static unsigned char asn[6] = /* Object ID is 1.2.643.2.2.3 */ -- 2.0.0.rc2 From dbaryshkov at gmail.com Fri Jun 6 20:48:34 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Fri, 6 Jun 2014 22:48:34 +0400 Subject: [PATCH 08/10] Fixup curve name in the GOST2012 test case In-Reply-To: <1402080516-8098-1-git-send-email-dbaryshkov@gmail.com> References: <1402080516-8098-1-git-send-email-dbaryshkov@gmail.com> Message-ID: <1402080516-8098-9-git-send-email-dbaryshkov@gmail.com> * tests/basic.c (check_pubkey): fixup curve name in public key. Signed-off-by: Dmitry Eremin-Solenikov --- tests/basic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/basic.c b/tests/basic.c index 875b36c..6d70cfd 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -6966,7 +6966,7 @@ check_pubkey (void) "(public-key\n" " (ecc\n" - " (curve GOST2001-test)\n" + " (curve GOST2012-test)\n" " (q #04115DC5BC96760C7B48598D8AB9E740D4C4A85A65BE33C1" " 815B5C320C854621DD5A515856D13314AF69BC5B924C8B" " 4DDFF75C45415C1D9DD9DD33612CD530EFE137C7C90CD4" -- 2.0.0.rc2 From dbaryshkov at gmail.com Fri Jun 6 20:48:35 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Fri, 6 Jun 2014 22:48:35 +0400 Subject: [PATCH 09/10] gost28147: use bufhelp helpers In-Reply-To: <1402080516-8098-1-git-send-email-dbaryshkov@gmail.com> References: <1402080516-8098-1-git-send-email-dbaryshkov@gmail.com> Message-ID: <1402080516-8098-10-git-send-email-dbaryshkov@gmail.com> * cipher/gost28147.c (gost_setkey, gost_encrypt_block, gost_decrypt_block): use buf_get_le32/buf_put_le32 helpers. -- On my box this boosts GOST 28147-89 speed from 36 MiB/s up to 44.5 MiB/s. Signed-off-by: Dmitry Eremin-Solenikov --- cipher/gost28147.c | 46 ++++++++++------------------------------------ 1 file changed, 10 insertions(+), 36 deletions(-) diff --git a/cipher/gost28147.c b/cipher/gost28147.c index 453a024..0841722 100644 --- a/cipher/gost28147.c +++ b/cipher/gost28147.c @@ -33,6 +33,7 @@ #include "types.h" #include "g10lib.h" #include "cipher.h" +#include "bufhelp.h" #include "gost.h" #include "gost-sb.h" @@ -51,10 +52,7 @@ gost_setkey (void *c, const byte *key, unsigned keylen) for (i = 0; i < 8; i++) { - ctx->key[i] = (key[4 * i + 3] << 24) | - (key[4 * i + 2] << 16) | - (key[4 * i + 1] << 8) | - (key[4 * i + 0] << 0); + ctx->key[i] = buf_get_le32(&key[4*i]); } return GPG_ERR_NO_ERROR; } @@ -76,14 +74,8 @@ gost_encrypt_block (void *c, byte *outbuf, const byte *inbuf) GOST28147_context *ctx = c; u32 n1, n2; - n1 = (inbuf[0] << 0) | - (inbuf[1] << 8) | - (inbuf[2] << 16) | - (inbuf[3] << 24); - n2 = (inbuf[4] << 0) | - (inbuf[5] << 8) | - (inbuf[6] << 16) | - (inbuf[7] << 24); + n1 = buf_get_le32 (inbuf); + n2 = buf_get_le32 (inbuf+4); n2 ^= gost_val (ctx, n1, 0); n1 ^= gost_val (ctx, n2, 1); n2 ^= gost_val (ctx, n1, 2); n1 ^= gost_val (ctx, n2, 3); @@ -105,14 +97,8 @@ gost_encrypt_block (void *c, byte *outbuf, const byte *inbuf) n2 ^= gost_val (ctx, n1, 3); n1 ^= gost_val (ctx, n2, 2); n2 ^= gost_val (ctx, n1, 1); n1 ^= gost_val (ctx, n2, 0); - outbuf[0 + 0] = (n2 >> (0 * 8)) & 0xff; - outbuf[1 + 0] = (n2 >> (1 * 8)) & 0xff; - outbuf[2 + 0] = (n2 >> (2 * 8)) & 0xff; - outbuf[3 + 0] = (n2 >> (3 * 8)) & 0xff; - outbuf[0 + 4] = (n1 >> (0 * 8)) & 0xff; - outbuf[1 + 4] = (n1 >> (1 * 8)) & 0xff; - outbuf[2 + 4] = (n1 >> (2 * 8)) & 0xff; - outbuf[3 + 4] = (n1 >> (3 * 8)) & 0xff; + buf_put_le32 (outbuf+0, n2); + buf_put_le32 (outbuf+4, n1); return /* burn_stack */ 4*sizeof(void*) /* func call */ + 3*sizeof(void*) /* stack */ + @@ -136,14 +122,8 @@ gost_decrypt_block (void *c, byte *outbuf, const byte *inbuf) GOST28147_context *ctx = c; u32 n1, n2; - n1 = (inbuf[0] << 0) | - (inbuf[1] << 8) | - (inbuf[2] << 16) | - (inbuf[3] << 24); - n2 = (inbuf[4] << 0) | - (inbuf[5] << 8) | - (inbuf[6] << 16) | - (inbuf[7] << 24); + n1 = buf_get_le32 (inbuf); + n2 = buf_get_le32 (inbuf+4); n2 ^= gost_val (ctx, n1, 0); n1 ^= gost_val (ctx, n2, 1); n2 ^= gost_val (ctx, n1, 2); n1 ^= gost_val (ctx, n2, 3); @@ -165,14 +145,8 @@ gost_decrypt_block (void *c, byte *outbuf, const byte *inbuf) n2 ^= gost_val (ctx, n1, 3); n1 ^= gost_val (ctx, n2, 2); n2 ^= gost_val (ctx, n1, 1); n1 ^= gost_val (ctx, n2, 0); - outbuf[0 + 0] = (n2 >> (0 * 8)) & 0xff; - outbuf[1 + 0] = (n2 >> (1 * 8)) & 0xff; - outbuf[2 + 0] = (n2 >> (2 * 8)) & 0xff; - outbuf[3 + 0] = (n2 >> (3 * 8)) & 0xff; - outbuf[0 + 4] = (n1 >> (0 * 8)) & 0xff; - outbuf[1 + 4] = (n1 >> (1 * 8)) & 0xff; - outbuf[2 + 4] = (n1 >> (2 * 8)) & 0xff; - outbuf[3 + 4] = (n1 >> (3 * 8)) & 0xff; + buf_put_le32 (outbuf+0, n2); + buf_put_le32 (outbuf+4, n1); return /* burn_stack */ 4*sizeof(void*) /* func call */ + 3*sizeof(void*) /* stack */ + -- 2.0.0.rc2 From dbaryshkov at gmail.com Fri Jun 6 20:48:32 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Fri, 6 Jun 2014 22:48:32 +0400 Subject: [PATCH 06/10] Add GOST R 34.11-94 variant using id-GostR3411-94-CryptoProParamSet In-Reply-To: <1402080516-8098-1-git-send-email-dbaryshkov@gmail.com> References: <1402080516-8098-1-git-send-email-dbaryshkov@gmail.com> Message-ID: <1402080516-8098-7-git-send-email-dbaryshkov@gmail.com> * src/gcrypt.h.in (GCRY_MD_GOSTR3411_CP): New. * src/cipher.h (_gcry_digest_spec_gost3411_cp): New. * cipher/gost28147.c (_gcry_gost_enc_one): Differentiate between CryptoPro and Test S-Boxes. * cipher/gostr3411-94.c (_gcry_digest_spec_gost3411_cp, gost3411_cp_init): New. * cipher/md.c (md_open): GCRY_MD_GOSTR3411_CP also uses B=32. -- RFC4357 defines only two S-Boxes that should be used together with GOST R 34.11-94 - a testing one (from standard itself, for testing only) and CryptoPro one. Instead of adding a separate gcry_md_ctrl() function just to switch s-boxes, add a separate MD algorithm using CryptoPro S-box. Signed-off-by: Dmitry Eremin-Solenikov --- cipher/gost.h | 2 +- cipher/gost28147.c | 6 +++++- cipher/gostr3411-94.c | 29 +++++++++++++++++++++++------ cipher/md.c | 2 ++ src/cipher.h | 1 + src/gcrypt.h.in | 3 ++- 6 files changed, 34 insertions(+), 9 deletions(-) diff --git a/cipher/gost.h b/cipher/gost.h index 3fbd9df..caaf34b 100644 --- a/cipher/gost.h +++ b/cipher/gost.h @@ -27,6 +27,6 @@ typedef struct { /* This is a simple interface that will be used by GOST R 34.11-94 */ extern unsigned int _gcry_gost_enc_one (GOST28147_context *c, const byte *key, - byte *out, byte *in); + byte *out, byte *in, int cryptopro); #endif diff --git a/cipher/gost28147.c b/cipher/gost28147.c index 52d0946..453a024 100644 --- a/cipher/gost28147.c +++ b/cipher/gost28147.c @@ -120,8 +120,12 @@ gost_encrypt_block (void *c, byte *outbuf, const byte *inbuf) } unsigned int _gcry_gost_enc_one (GOST28147_context *c, const byte *key, - byte *out, byte *in) + byte *out, byte *in, int cryptopro) { + if (cryptopro) + c->sbox = sbox_CryptoPro_3411; + else + c->sbox = sbox_test_3411; gost_setkey (c, key, 32); return gost_encrypt_block (c, out, in) + 5 * sizeof(void *); } diff --git a/cipher/gostr3411-94.c b/cipher/gostr3411-94.c index 73d570f..9d065fb 100644 --- a/cipher/gostr3411-94.c +++ b/cipher/gostr3411-94.c @@ -38,6 +38,7 @@ typedef struct { byte h[32]; byte sigma[32]; u32 len; + int cryptopro; } GOSTR3411_CONTEXT; static unsigned int @@ -58,6 +59,15 @@ gost3411_init (void *context, unsigned int flags) hd->bctx.count = 0; hd->bctx.blocksize = 32; hd->bctx.bwrite = transform; + hd->cryptopro = 0; +} + +static void +gost3411_cp_init (void *context, unsigned int flags) +{ + GOSTR3411_CONTEXT *hd = context; + gost3411_init (context, flags); + hd->cryptopro = 1; } static void @@ -153,7 +163,7 @@ do_add (unsigned char *s, unsigned char *a) } static unsigned int -do_hash_step (GOST28147_context *hd, unsigned char *h, unsigned char *m) +do_hash_step (GOSTR3411_CONTEXT *hd, unsigned char *h, unsigned char *m) { unsigned char u[32], v[32], s[32]; unsigned char k[32]; @@ -166,7 +176,7 @@ do_hash_step (GOST28147_context *hd, unsigned char *h, unsigned char *m) for (i = 0; i < 4; i++) { do_p (k, u, v); - burn = _gcry_gost_enc_one (hd, k, s + i*8, h + i*8); + burn = _gcry_gost_enc_one (&hd->hd, k, s + i*8, h + i*8, hd->cryptopro); do_a (u); if (i == 1) @@ -220,7 +230,7 @@ transform_blk (void *ctx, const unsigned char *data) unsigned int burn; memcpy (m, data, 32); - burn = do_hash_step (&hd->hd, hd->h, m); + burn = do_hash_step (hd, hd->h, m); do_add (hd->sigma, m); return /* burn_stack */ burn + 3 * sizeof(void*) + 32 + 2 * sizeof(void*); @@ -283,8 +293,8 @@ gost3411_final (void *context) nblocks /= 256; } - do_hash_step (&hd->hd, hd->h, l); - do_hash_step (&hd->hd, hd->h, hd->sigma); + do_hash_step (hd, hd->h, l); + do_hash_step (hd, hd->h, hd->sigma); } static byte * @@ -310,7 +320,14 @@ static gcry_md_oid_spec_t oid_spec_gostr3411[] = gcry_md_spec_t _gcry_digest_spec_gost3411_94 = { GCRY_MD_GOSTR3411_94, {0, 0}, - "GOSTR3411_94", asn, DIM (asn), oid_spec_gostr3411, 32, + "GOSTR3411_94", NULL, 0, NULL, 32, gost3411_init, _gcry_md_block_write, gost3411_final, gost3411_read, sizeof (GOSTR3411_CONTEXT) }; +gcry_md_spec_t _gcry_digest_spec_gost3411_cp = + { + GCRY_MD_GOSTR3411_CP, {0, 0}, + "GOSTR3411_CP", asn, DIM (asn), oid_spec_gostr3411, 32, + gost3411_cp_init, _gcry_md_block_write, gost3411_final, gost3411_read, + sizeof (GOSTR3411_CONTEXT) + }; diff --git a/cipher/md.c b/cipher/md.c index 5ab89cb..a1e5859 100644 --- a/cipher/md.c +++ b/cipher/md.c @@ -53,6 +53,7 @@ static gcry_md_spec_t *digest_list[] = #endif #ifdef USE_GOST_R_3411_94 &_gcry_digest_spec_gost3411_94, + &_gcry_digest_spec_gost3411_cp, #endif #ifdef USE_GOST_R_3411_12 &_gcry_digest_spec_stribog_256, @@ -335,6 +336,7 @@ md_open (gcry_md_hd_t *h, int algo, unsigned int flags) ctx->macpads_Bsize = 128; break; case GCRY_MD_GOSTR3411_94: + case GCRY_MD_GOSTR3411_CP: ctx->macpads_Bsize = 32; break; default: diff --git a/src/cipher.h b/src/cipher.h index ed57d3c..f4f6cc4 100644 --- a/src/cipher.h +++ b/src/cipher.h @@ -258,6 +258,7 @@ extern gcry_md_spec_t _gcry_digest_spec_crc32; extern gcry_md_spec_t _gcry_digest_spec_crc32_rfc1510; extern gcry_md_spec_t _gcry_digest_spec_crc24_rfc2440; extern gcry_md_spec_t _gcry_digest_spec_gost3411_94; +extern gcry_md_spec_t _gcry_digest_spec_gost3411_cp; extern gcry_md_spec_t _gcry_digest_spec_stribog_256; extern gcry_md_spec_t _gcry_digest_spec_stribog_512; extern gcry_md_spec_t _gcry_digest_spec_md2; diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index 95d324b..a5f8350 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -1152,7 +1152,8 @@ enum gcry_md_algos GCRY_MD_TIGER2 = 307, /* TIGER2 variant. */ GCRY_MD_GOSTR3411_94 = 308, /* GOST R 34.11-94. */ GCRY_MD_STRIBOG256 = 309, /* GOST R 34.11-2012, 256 bit. */ - GCRY_MD_STRIBOG512 = 310 /* GOST R 34.11-2012, 512 bit. */ + GCRY_MD_STRIBOG512 = 310, /* GOST R 34.11-2012, 512 bit. */ + GCRY_MD_GOSTR3411_CP = 311 /* GOST R 34.11-94 with CryptoPro-A S-Box. */ }; /* Flags used with the open function. */ -- 2.0.0.rc2 From dbaryshkov at gmail.com Fri Jun 6 20:48:26 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Fri, 6 Jun 2014 22:48:26 +0400 Subject: [PATCH 01/10] GOST R 34.11-94 add OIDs Message-ID: <1402080516-8098-1-git-send-email-dbaryshkov@gmail.com> * cipher/gostr3411-94.c: Add OIDs for GOST R 34.11-94 from RFC 4357. Signed-off-by: Dmitry Eremin-Solenikov --- cipher/gostr3411-94.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/cipher/gostr3411-94.c b/cipher/gostr3411-94.c index 9a39733..73d570f 100644 --- a/cipher/gostr3411-94.c +++ b/cipher/gostr3411-94.c @@ -294,10 +294,23 @@ gost3411_read (void *context) return hd->h; } + +static unsigned char asn[6] = /* Object ID is 1.2.643.2.2.3 */ + { 0x2a, 0x85, 0x03, 0x02, 0x02, 0x03 }; + +static gcry_md_oid_spec_t oid_spec_gostr3411[] = + { + /* iso.member-body.ru.rans.cryptopro.3 (gostR3411-94-with-gostR3410-2001) */ + { "1.2.643.2.2.3" }, + /* iso.member-body.ru.rans.cryptopro.9 (gostR3411-94) */ + { "1.2.643.2.2.9" }, + {NULL}, + }; + gcry_md_spec_t _gcry_digest_spec_gost3411_94 = { GCRY_MD_GOSTR3411_94, {0, 0}, - "GOSTR3411_94", NULL, 0, NULL, 32, + "GOSTR3411_94", asn, DIM (asn), oid_spec_gostr3411, 32, gost3411_init, _gcry_md_block_write, gost3411_final, gost3411_read, sizeof (GOSTR3411_CONTEXT) }; -- 2.0.0.rc2 From dbaryshkov at gmail.com Fri Jun 6 20:48:33 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Fri, 6 Jun 2014 22:48:33 +0400 Subject: [PATCH 07/10] Update PBKDF2 tests with GOST R 34.11-94 test cases In-Reply-To: <1402080516-8098-1-git-send-email-dbaryshkov@gmail.com> References: <1402080516-8098-1-git-send-email-dbaryshkov@gmail.com> Message-ID: <1402080516-8098-8-git-send-email-dbaryshkov@gmail.com> * tests/t-kdf.c (check_pbkdf2): Add MD_GOSTR3411_CP test cases. -- TC26 (Technical Comitee for standardization "Cryptography and security mechanisms") published a document with test vectors for PBKDF2 used with GOST R 34.11-94 message digest function. Signed-off-by: Dmitry Eremin-Solenikov --- tests/t-kdf.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 3 deletions(-) diff --git a/tests/t-kdf.c b/tests/t-kdf.c index adbe6cc..8e728d5 100644 --- a/tests/t-kdf.c +++ b/tests/t-kdf.c @@ -864,6 +864,7 @@ check_pbkdf2 (void) size_t plen; /* Length of P. */ const char *salt; size_t saltlen; + int hashalgo; unsigned long c; /* Iterations. */ int dklen; /* Requested key length. */ const char *dk; /* Derived key. */ @@ -872,6 +873,7 @@ check_pbkdf2 (void) { "password", 8, "salt", 4, + GCRY_MD_SHA1, 1, 20, "\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9" @@ -880,6 +882,7 @@ check_pbkdf2 (void) { "password", 8, "salt", 4, + GCRY_MD_SHA1, 2, 20, "\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c\xcd\x1e" @@ -888,6 +891,7 @@ check_pbkdf2 (void) { "password", 8, "salt", 4, + GCRY_MD_SHA1, 4096, 20, "\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad" @@ -896,6 +900,7 @@ check_pbkdf2 (void) { "password", 8, "salt", 4, + GCRY_MD_SHA1, 16777216, 20, "\xee\xfe\x3d\x61\xcd\x4d\xa4\xe4\xe9\x94" @@ -905,6 +910,7 @@ check_pbkdf2 (void) { "passwordPASSWORDpassword", 24, "saltSALTsaltSALTsaltSALTsaltSALTsalt", 36, + GCRY_MD_SHA1, 4096, 25, "\x3d\x2e\xec\x4f\xe4\x1c\x84\x9b\x80\xc8" @@ -914,6 +920,7 @@ check_pbkdf2 (void) { "pass\0word", 9, "sa\0lt", 5, + GCRY_MD_SHA1, 4096, 16, "\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37" @@ -922,15 +929,71 @@ check_pbkdf2 (void) { /* empty password test, not in RFC-6070 */ "", 0, "salt", 4, + GCRY_MD_SHA1, 2, 20, "\x13\x3a\x4c\xe8\x37\xb4\xd2\x52\x1e\xe2" "\xbf\x03\xe1\x1c\x71\xca\x79\x4e\x07\x97" + }, + { + "password", 8, + "salt", 4, + GCRY_MD_GOSTR3411_CP, + 1, + 32, + "\x73\x14\xe7\xc0\x4f\xb2\xe6\x62\xc5\x43\x67\x42\x53\xf6\x8b\xd0" + "\xb7\x34\x45\xd0\x7f\x24\x1b\xed\x87\x28\x82\xda\x21\x66\x2d\x58" + }, + { + "password", 8, + "salt", 4, + GCRY_MD_GOSTR3411_CP, + 2, + 32, + "\x99\x0d\xfa\x2b\xd9\x65\x63\x9b\xa4\x8b\x07\xb7\x92\x77\x5d\xf7" + "\x9f\x2d\xb3\x4f\xef\x25\xf2\x74\x37\x88\x72\xfe\xd7\xed\x1b\xb3" + }, + { + "password", 8, + "salt", 4, + GCRY_MD_GOSTR3411_CP, + 4096, + 32, + "\x1f\x18\x29\xa9\x4b\xdf\xf5\xbe\x10\xd0\xae\xb3\x6a\xf4\x98\xe7" + "\xa9\x74\x67\xf3\xb3\x11\x16\xa5\xa7\xc1\xaf\xff\x9d\xea\xda\xfe" + }, + /* { -- takes too long (4-5 min) to calculate + "password", 8, + "salt", 4, + GCRY_MD_GOSTR3411_CP, + 16777216, + 32, + "\xa5\x7a\xe5\xa6\x08\x83\x96\xd1\x20\x85\x0c\x5c\x09\xde\x0a\x52" + "\x51\x00\x93\x8a\x59\xb1\xb5\xc3\xf7\x81\x09\x10\xd0\x5f\xcd\x97" + }, */ + { + "passwordPASSWORDpassword", 24, + "saltSALTsaltSALTsaltSALTsaltSALTsalt", 36, + GCRY_MD_GOSTR3411_CP, + 4096, + 40, + "\x78\x83\x58\xc6\x9c\xb2\xdb\xe2\x51\xa7\xbb\x17\xd5\xf4\x24\x1f" + "\x26\x5a\x79\x2a\x35\xbe\xcd\xe8\xd5\x6f\x32\x6b\x49\xc8\x50\x47" + "\xb7\x63\x8a\xcb\x47\x64\xb1\xfd" + }, + { + "pass\0word", 9, + "sa\0lt", 5, + GCRY_MD_GOSTR3411_CP, + 4096, + 20, + "\x43\xe0\x6c\x55\x90\xb0\x8c\x02\x25\x24" + "\x23\x73\x12\x7e\xdf\x9c\x8e\x9c\x32\x91" } }; int tvidx; gpg_error_t err; - unsigned char outbuf[32]; + unsigned char outbuf[40]; int i; for (tvidx=0; tvidx < DIM(tv); tvidx++) @@ -938,10 +1001,11 @@ check_pbkdf2 (void) if (tv[tvidx].disabled) continue; if (verbose) - fprintf (stderr, "checking PBKDF2 test vector %d\n", tvidx); + fprintf (stderr, "checking PBKDF2 test vector %d algo %d\n", tvidx, + tv[tvidx].hashalgo); assert (tv[tvidx].dklen <= sizeof outbuf); err = gcry_kdf_derive (tv[tvidx].p, tv[tvidx].plen, - GCRY_KDF_PBKDF2, GCRY_MD_SHA1, + GCRY_KDF_PBKDF2, tv[tvidx].hashalgo, tv[tvidx].salt, tv[tvidx].saltlen, tv[tvidx].c, tv[tvidx].dklen, outbuf); if (err) -- 2.0.0.rc2 From dbaryshkov at gmail.com Fri Jun 6 20:48:29 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Fri, 6 Jun 2014 22:48:29 +0400 Subject: [PATCH 03/10] cipher/gost28147: generate optimized s-boxes from compact ones In-Reply-To: <1402080516-8098-1-git-send-email-dbaryshkov@gmail.com> References: <1402080516-8098-1-git-send-email-dbaryshkov@gmail.com> Message-ID: <1402080516-8098-4-git-send-email-dbaryshkov@gmail.com> * cipher/gost-s-box.c: New. Outputs optimized expanded representation of s-boxes (4x256) from compact 16x8 representation. * cipher/Makefile.am: Add gost-sb.h dependency to gost28147.lo * cipher/gost.h: Add sbox to the GOST28147_context structure. * cipher/gost28147.c (gost_setkey): Set default s-box to test s-box from GOST R 34.11 (this was the only one S-box before). * cipher/gost28147.c (gost_val): Use sbox from the context. Signed-off-by: Dmitry Eremin-Solenikov --- .gitignore | 2 + cipher/Makefile.am | 5 + cipher/gost-s-box.c | 256 +++++++++++++++++++++++++++++++++++++++++++++++ cipher/gost.h | 1 + cipher/gost28147.c | 282 ++-------------------------------------------------- 5 files changed, 272 insertions(+), 274 deletions(-) create mode 100644 cipher/gost-s-box.c diff --git a/.gitignore b/.gitignore index 8b235f9..3929e4d 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,8 @@ po/messages.mo /stamp-h1 /Makefile.in cipher/Makefile.in +cipher/gost-s-box +cipher/gost-sb.h compat/Makefile.in doc/Makefile.in m4/Makefile.in diff --git a/cipher/Makefile.am b/cipher/Makefile.am index 8a3bd19..c165356 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -93,6 +93,11 @@ rfc2268.c \ camellia.c camellia.h camellia-glue.c camellia-aesni-avx-amd64.S \ camellia-aesni-avx2-amd64.S camellia-arm.S +noinst_PROGRAMS = gost-s-box +gost28147.lo: gost-sb.h +gost-sb.h: gost-s-box + $(builddir)/gost-s-box $@ + if ENABLE_O_FLAG_MUNGING o_flag_munging = sed -e 's/-O\([2-9s][2-9s]*\)/-O1/' -e 's/-Ofast/-O1/g' else diff --git a/cipher/gost-s-box.c b/cipher/gost-s-box.c new file mode 100644 index 0000000..0094f65 --- /dev/null +++ b/cipher/gost-s-box.c @@ -0,0 +1,256 @@ +/* gost-s-box.c - GOST 28147-89 S-Box expander + * Copyright (C) 2013 Dmitry Eremin-Solenikov + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + */ + +#include +#include + +#define DIM(v) (sizeof(v)/sizeof((v)[0])) + +struct gost_sbox +{ + const char *name; + const char *oid; + unsigned char sbox[16*8]; +} gost_sboxes[] = { + { "test_3411", "1.2.643.2.2.30.0", { + 0x4, 0xE, 0x5, 0x7, 0x6, 0x4, 0xD, 0x1, + 0xA, 0xB, 0x8, 0xD, 0xC, 0xB, 0xB, 0xF, + 0x9, 0x4, 0x1, 0xA, 0x7, 0xA, 0x4, 0xD, + 0x2, 0xC, 0xD, 0x1, 0x1, 0x0, 0x1, 0x0, + + 0xD, 0x6, 0xA, 0x0, 0x5, 0x7, 0x3, 0x5, + 0x8, 0xD, 0x3, 0x8, 0xF, 0x2, 0xF, 0x7, + 0x0, 0xF, 0x4, 0x9, 0xD, 0x1, 0x5, 0xA, + 0xE, 0xA, 0x2, 0xF, 0x8, 0xD, 0x9, 0x4, + + 0x6, 0x2, 0xE, 0xE, 0x4, 0x3, 0x0, 0x9, + 0xB, 0x3, 0xF, 0x4, 0xA, 0x6, 0xA, 0x2, + 0x1, 0x8, 0xC, 0x6, 0x9, 0x8, 0xE, 0x3, + 0xC, 0x1, 0x7, 0xC, 0xE, 0x5, 0x7, 0xE, + + 0x7, 0x0, 0x6, 0xB, 0x0, 0x9, 0x6, 0x6, + 0xF, 0x7, 0x0, 0x2, 0x3, 0xC, 0x8, 0xB, + 0x5, 0x5, 0x9, 0x5, 0xB, 0xF, 0x2, 0x8, + 0x3, 0x9, 0xB, 0x3, 0x2, 0xE, 0xC, 0xC, + } + }, + { "CryptoPro_3411", "1.2.643.2.2.30.1", { + 0xA, 0x5, 0x7, 0x4, 0x7, 0x7, 0xD, 0x1, + 0x4, 0xF, 0xF, 0xA, 0x6, 0x6, 0xE, 0x3, + 0x5, 0x4, 0xC, 0x7, 0x4, 0x2, 0x4, 0xA, + 0x6, 0x0, 0xE, 0xC, 0xB, 0x4, 0x1, 0x9, + + 0x8, 0x2, 0x9, 0x0, 0x9, 0xD, 0x7, 0x5, + 0x1, 0xD, 0x4, 0xF, 0xC, 0x9, 0x0, 0xB, + 0x3, 0xB, 0x1, 0x2, 0x2, 0xF, 0x5, 0x4, + 0x7, 0x9, 0x0, 0x8, 0xA, 0x0, 0xA, 0xF, + + 0xD, 0x1, 0x3, 0xE, 0x1, 0xA, 0x3, 0x8, + 0xC, 0x7, 0xB, 0x1, 0x8, 0x1, 0xC, 0x6, + 0xE, 0x6, 0x5, 0x6, 0x0, 0x5, 0x8, 0x7, + 0x0, 0x3, 0x2, 0x5, 0xE, 0xB, 0xF, 0xE, + + 0x9, 0xC, 0x6, 0xD, 0xF, 0x8, 0x6, 0xD, + 0x2, 0xE, 0xA, 0xB, 0xD, 0xE, 0x2, 0x0, + 0xB, 0xA, 0x8, 0x9, 0x3, 0xC, 0x9, 0x2, + 0xF, 0x8, 0xD, 0x3, 0x5, 0x3, 0xB, 0xC, + } + }, + { "Test_89", "1.2.643.2.2.31.0", { + 0x4, 0xC, 0xD, 0xE, 0x3, 0x8, 0x9, 0xC, + 0x2, 0x9, 0x8, 0x9, 0xE, 0xF, 0xB, 0x6, + 0xF, 0xF, 0xE, 0xB, 0x5, 0x6, 0xC, 0x5, + 0x5, 0xE, 0xC, 0x2, 0x9, 0xB, 0x0, 0x2, + + 0x9, 0x8, 0x7, 0x5, 0x6, 0x1, 0x3, 0xB, + 0x1, 0x1, 0x3, 0xF, 0x8, 0x9, 0x6, 0x0, + 0x0, 0x3, 0x9, 0x7, 0x0, 0xC, 0x7, 0x9, + 0x8, 0xA, 0xA, 0x1, 0xD, 0x5, 0x5, 0xD, + + 0xE, 0x2, 0x1, 0x0, 0xA, 0xD, 0x4, 0x3, + 0x3, 0x7, 0x5, 0xD, 0xB, 0x3, 0x8, 0xE, + 0xB, 0x4, 0x2, 0xC, 0x7, 0x7, 0xE, 0x7, + 0xC, 0xD, 0x4, 0x6, 0xC, 0xA, 0xF, 0xA, + + 0xD, 0x6, 0x6, 0xA, 0x2, 0x0, 0x1, 0xF, + 0x7, 0x0, 0xF, 0x4, 0x1, 0xE, 0xA, 0x4, + 0xA, 0xB, 0x0, 0x3, 0xF, 0x2, 0x2, 0x1, + 0x6, 0x5, 0xB, 0x8, 0x4, 0x4, 0xD, 0x8, + } + }, + { "CryptoPro_A", "1.2.643.2.2.31.1", { + 0x9, 0x3, 0xE, 0xE, 0xB, 0x3, 0x1, 0xB, + 0x6, 0x7, 0x4, 0x7, 0x5, 0xA, 0xD, 0xA, + 0x3, 0xE, 0x6, 0xA, 0x1, 0xD, 0x2, 0xF, + 0x2, 0x9, 0x2, 0xC, 0x9, 0xC, 0x9, 0x5, + + 0x8, 0x8, 0xB, 0xD, 0x8, 0x1, 0x7, 0x0, + 0xB, 0xA, 0x3, 0x1, 0xD, 0x2, 0xA, 0xC, + 0x1, 0xF, 0xD, 0x3, 0xF, 0x0, 0x6, 0xE, + 0x7, 0x0, 0x8, 0x9, 0x0, 0xB, 0x0, 0x8, + + 0xA, 0x5, 0xC, 0x0, 0xE, 0x7, 0x8, 0x6, + 0x4, 0x2, 0xF, 0x2, 0x4, 0x5, 0xC, 0x2, + 0xE, 0x6, 0x5, 0xB, 0x2, 0x9, 0x4, 0x3, + 0xF, 0xC, 0xA, 0x4, 0x3, 0x4, 0x5, 0x9, + + 0xC, 0xB, 0x0, 0xF, 0xC, 0x8, 0xF, 0x1, + 0x0, 0x4, 0x7, 0x8, 0x7, 0xF, 0x3, 0x7, + 0xD, 0xD, 0x1, 0x5, 0xA, 0xE, 0xB, 0xD, + 0x5, 0x1, 0x9, 0x6, 0x6, 0x6, 0xE, 0x4, + } + }, + { "CryptoPro_B", "1.2.643.2.2.31.2", { + 0x8, 0x0, 0xE, 0x7, 0x2, 0x8, 0x5, 0x0, + 0x4, 0x1, 0xC, 0x5, 0x7, 0x3, 0x2, 0x4, + 0xB, 0x2, 0x0, 0x0, 0xC, 0x2, 0xA, 0xB, + 0x1, 0xA, 0xA, 0xD, 0xF, 0x6, 0xB, 0xE, + + 0x3, 0x4, 0x9, 0xB, 0x9, 0x4, 0x9, 0x8, + 0x5, 0xD, 0x2, 0x6, 0x5, 0xD, 0x1, 0x3, + 0x0, 0x5, 0xD, 0x1, 0xA, 0xE, 0xC, 0x7, + 0x9, 0xC, 0xB, 0x2, 0xB, 0xB, 0x3, 0x1, + + 0x2, 0x9, 0x7, 0x3, 0x1, 0xC, 0x7, 0xA, + 0xE, 0x7, 0x5, 0xA, 0x4, 0x1, 0x4, 0x2, + 0xA, 0x3, 0x8, 0xC, 0x0, 0x7, 0xD, 0x9, + 0xC, 0xF, 0xF, 0xF, 0xD, 0xF, 0x0, 0x6, + + 0x6, 0x8, 0x6, 0xE, 0x8, 0x0, 0xF, 0xD, + 0x7, 0x6, 0x1, 0x9, 0xE, 0x9, 0x8, 0x5, + 0xF, 0xE, 0x4, 0x8, 0x3, 0x5, 0xE, 0xC, + } + }, + { "CryptoPro_C", "1.2.643.2.2.31.3", { + 0x1, 0x0, 0x8, 0x3, 0x8, 0xC, 0xA, 0x7, + 0xB, 0x1, 0x2, 0x6, 0xD, 0x9, 0x9, 0x4, + 0xC, 0x7, 0x5, 0x0, 0xB, 0xB, 0x6, 0x0, + 0x2, 0xD, 0x0, 0x1, 0x0, 0x1, 0x8, 0x5, + + 0x9, 0xB, 0x4, 0x5, 0x4, 0x8, 0xD, 0xA, + 0xD, 0x4, 0x9, 0xD, 0x5, 0xE, 0xE, 0x2, + 0x0, 0x5, 0xF, 0xA, 0x1, 0x2, 0x2, 0xF, + 0xF, 0x2, 0xA, 0x8, 0x2, 0x4, 0x0, 0xE, + + 0x4, 0x8, 0x3, 0xB, 0x9, 0x7, 0xF, 0xC, + 0x5, 0xE, 0x7, 0x2, 0x3, 0x3, 0x3, 0x6, + 0x8, 0xF, 0xC, 0x9, 0xC, 0x6, 0x5, 0x1, + 0xE, 0xC, 0xD, 0x7, 0xE, 0x5, 0xB, 0xB, + + 0xA, 0x9, 0x6, 0xE, 0x6, 0xA, 0x4, 0xD, + 0x7, 0xA, 0xE, 0xF, 0xF, 0x0, 0x1, 0x9, + 0x6, 0x6, 0x1, 0xC, 0xA, 0xF, 0xC, 0x3, + 0x3, 0x3, 0xB, 0x4, 0x7, 0xD, 0x7, 0x8, + } + }, + { "CryptoPro_D", "1.2.643.2.2.31.4", { + 0xF, 0xB, 0x1, 0x1, 0x0, 0x8, 0x3, 0x1, + 0xC, 0x6, 0xC, 0x5, 0xC, 0x0, 0x0, 0xA, + 0x2, 0x3, 0xB, 0xE, 0x8, 0xF, 0x6, 0x6, + 0xA, 0x4, 0x0, 0xC, 0x9, 0x3, 0xF, 0x8, + + 0x6, 0xC, 0xF, 0xA, 0xD, 0x2, 0x1, 0xF, + 0x4, 0xF, 0xE, 0x7, 0x2, 0x5, 0xE, 0xB, + 0x5, 0xE, 0x6, 0x0, 0xA, 0xE, 0x9, 0x0, + 0x0, 0x2, 0x5, 0xD, 0xB, 0xB, 0x2, 0x4, + + 0x7, 0x7, 0xA, 0x6, 0x7, 0x1, 0xD, 0xC, + 0x9, 0xD, 0xD, 0x2, 0x3, 0xA, 0x8, 0x3, + 0xE, 0x8, 0x4, 0xB, 0x6, 0x4, 0xC, 0x5, + 0xD, 0x0, 0x8, 0x4, 0x5, 0x7, 0x4, 0x9, + + 0x1, 0x5, 0x9, 0x9, 0x4, 0xC, 0xB, 0x7, + 0xB, 0xA, 0x3, 0x3, 0xE, 0x9, 0xA, 0xD, + 0x8, 0x9, 0x7, 0xF, 0xF, 0xD, 0x5, 0x2, + 0x3, 0x1, 0x2, 0x8, 0x1, 0x6, 0x7, 0xE, + } + }, + { "TC26_A", "1.2.643.7.1.2.5.1.1", { + 0xc, 0x6, 0xb, 0xc, 0x7, 0x5, 0x8, 0x1, + 0x4, 0x8, 0x3, 0x8, 0xf, 0xd, 0xe, 0x7, + 0x6, 0x2, 0x5, 0x2, 0x5, 0xf, 0x2, 0xe, + 0x2, 0x3, 0x8, 0x1, 0xa, 0x6, 0x5, 0xd, + + 0xa, 0x9, 0x2, 0xd, 0x8, 0x9, 0x6, 0x0, + 0x5, 0xa, 0xf, 0x4, 0x1, 0x2, 0x9, 0x5, + 0xb, 0x5, 0xa, 0xf, 0x6, 0xc, 0x1, 0x8, + 0x9, 0xc, 0xd, 0x6, 0xd, 0xa, 0xc, 0x3, + + 0xe, 0x1, 0xe, 0x7, 0x0, 0xb, 0xf, 0x4, + 0x8, 0xe, 0x1, 0x0, 0x9, 0x7, 0x4, 0xf, + 0xd, 0x4, 0x7, 0xa, 0x3, 0x8, 0xb, 0xa, + 0x7, 0x7, 0x4, 0x5, 0xe, 0x1, 0x0, 0x6, + + 0x0, 0xb, 0xc, 0x3, 0xb, 0x4, 0xd, 0x9, + 0x3, 0xd, 0x9, 0xe, 0x4, 0x3, 0xa, 0xc, + 0xf, 0x0, 0x6, 0x9, 0x2, 0xe, 0x3, 0xb, + 0x1, 0xf, 0x0, 0xb, 0xc, 0x0, 0x7, 0x2, + } + }, +}; + +int main(int argc, char **argv) +{ + unsigned int i, j, s; + FILE *f; + + if (argc == 1) + f = stdin; + else + f = fopen(argv[1], "w"); + + if (!f) + { + perror("fopen"); + exit(1); + } + + for (s = 0; s < DIM(gost_sboxes); s++) + { + unsigned char *sbox = gost_sboxes[s].sbox; + fprintf (f, "static const u32 sbox_%s[4*256] =\n {", gost_sboxes[s].name); + for (i = 0; i < 4; i++) { + fprintf (f, "\n /* %d */\n ", i); + for (j = 0; j < 256; j++) { + unsigned int val; + if (j % 4 == 0 && j != 0) + fprintf (f, "\n "); + val = sbox[ (j & 0xf) * 8 + 2 * i + 0] | + (sbox[ (j >> 4) * 8 + 2 * i + 1] << 4); + val <<= (8*i); + val = (val << 11) | (val >> 21); + fprintf (f, " 0x%08x,", val); + } + } + fprintf (f, "\n };\n\n"); + } + + fprintf (f, "static struct\n{\n const char *oid;\n const u32 *sbox;\n} gost_oid_map[] = {\n"); + + for (s = 0; s < DIM(gost_sboxes); s++) + { + fprintf (f, " { \"%s\", sbox_%s },\n", gost_sboxes[s].oid, gost_sboxes[s].name ); + } + + fprintf(f, " { NULL, NULL }\n};\n"); + + fclose (f); + + return 0; +} diff --git a/cipher/gost.h b/cipher/gost.h index d058eb2..3fbd9df 100644 --- a/cipher/gost.h +++ b/cipher/gost.h @@ -22,6 +22,7 @@ typedef struct { u32 key[8]; + const u32 *sbox; } GOST28147_context; /* This is a simple interface that will be used by GOST R 34.11-94 */ diff --git a/cipher/gost28147.c b/cipher/gost28147.c index 1e48eb0..1720f45 100644 --- a/cipher/gost28147.c +++ b/cipher/gost28147.c @@ -34,277 +34,8 @@ #include "g10lib.h" #include "cipher.h" - -/* This is an s-box from RFC4357, named GostR3411-94-TestParamSet - * For now it is the only s-box supported, as libgcrypt lacks mechanism - * for passing parameters to cipher in a usefull way. - * S-boxes was modified from 4->4 to 8->8 bits unit with precalculated - * shift and rotation by optimisation reasons. - */ -static const u32 test_sbox[4][256] = { - /* 0 */ - { 0x00072000, 0x00075000, 0x00074800, 0x00071000, - 0x00076800, 0x00074000, 0x00070000, 0x00077000, - 0x00073000, 0x00075800, 0x00070800, 0x00076000, - 0x00073800, 0x00077800, 0x00072800, 0x00071800, - 0x0005a000, 0x0005d000, 0x0005c800, 0x00059000, - 0x0005e800, 0x0005c000, 0x00058000, 0x0005f000, - 0x0005b000, 0x0005d800, 0x00058800, 0x0005e000, - 0x0005b800, 0X0005F800, 0x0005a800, 0x00059800, - 0x00022000, 0x00025000, 0x00024800, 0x00021000, - 0x00026800, 0x00024000, 0x00020000, 0x00027000, - 0X00023000, 0x00025800, 0x00020800, 0x00026000, - 0x00023800, 0x00027800, 0x00022800, 0x00021800, - 0x00062000, 0x00065000, 0x00064800, 0x00061000, - 0x00066800, 0x00064000, 0x00060000, 0x00067000, - 0x00063000, 0x00065800, 0x00060800, 0x00066000, - 0x00063800, 0x00067800, 0x00062800, 0x00061800, - 0x00032000, 0x00035000, 0x00034800, 0x00031000, - 0x00036800, 0x00034000, 0x00030000, 0x00037000, - 0x00033000, 0x00035800, 0x00030800, 0x00036000, - 0x00033800, 0x00037800, 0x00032800, 0x00031800, - 0x0006a000, 0x0006d000, 0x0006c800, 0x00069000, - 0x0006e800, 0x0006c000, 0x00068000, 0x0006f000, - 0x0006b000, 0x0006d800, 0x00068800, 0x0006e000, - 0x0006b800, 0x0006f800, 0x0006a800, 0x00069800, - 0x0007a000, 0x0007d000, 0x0007c800, 0x00079000, - 0x0007e800, 0x0007c000, 0x00078000, 0x0007f000, - 0x0007b000, 0x0007d800, 0x00078800, 0x0007e000, - 0x0007b800, 0x0007f800, 0x0007a800, 0x00079800, - 0x00052000, 0x00055000, 0x00054800, 0x00051000, - 0x00056800, 0x00054000, 0x00050000, 0x00057000, - 0x00053000, 0x00055800, 0x00050800, 0x00056000, - 0x00053800, 0x00057800, 0x00052800, 0x00051800, - 0x00012000, 0x00015000, 0x00014800, 0x00011000, - 0x00016800, 0x00014000, 0x00010000, 0x00017000, - 0x00013000, 0x00015800, 0x00010800, 0x00016000, - 0x00013800, 0x00017800, 0x00012800, 0x00011800, - 0x0001a000, 0x0001d000, 0x0001c800, 0x00019000, - 0x0001e800, 0x0001c000, 0x00018000, 0x0001f000, - 0x0001b000, 0x0001d800, 0x00018800, 0x0001e000, - 0x0001b800, 0x0001f800, 0x0001a800, 0x00019800, - 0x00042000, 0x00045000, 0x00044800, 0x00041000, - 0x00046800, 0x00044000, 0x00040000, 0x00047000, - 0x00043000, 0x00045800, 0x00040800, 0x00046000, - 0x00043800, 0x00047800, 0x00042800, 0x00041800, - 0x0000a000, 0x0000d000, 0x0000c800, 0x00009000, - 0x0000e800, 0x0000c000, 0x00008000, 0x0000f000, - 0x0000b000, 0x0000d800, 0x00008800, 0x0000e000, - 0x0000b800, 0x0000f800, 0x0000a800, 0x00009800, - 0x00002000, 0x00005000, 0x00004800, 0x00001000, - 0x00006800, 0x00004000, 0x00000000, 0x00007000, - 0x00003000, 0x00005800, 0x00000800, 0x00006000, - 0x00003800, 0x00007800, 0x00002800, 0x00001800, - 0x0003a000, 0x0003d000, 0x0003c800, 0x00039000, - 0x0003e800, 0x0003c000, 0x00038000, 0x0003f000, - 0x0003b000, 0x0003d800, 0x00038800, 0x0003e000, - 0x0003b800, 0x0003f800, 0x0003a800, 0x00039800, - 0x0002a000, 0x0002d000, 0x0002c800, 0x00029000, - 0x0002e800, 0x0002c000, 0x00028000, 0x0002f000, - 0x0002b000, 0x0002d800, 0x00028800, 0x0002e000, - 0x0002b800, 0x0002f800, 0x0002a800, 0x00029800, - 0x0004a000, 0x0004d000, 0x0004c800, 0x00049000, - 0x0004e800, 0x0004c000, 0x00048000, 0x0004f000, - 0x0004b000, 0x0004d800, 0x00048800, 0x0004e000, - 0x0004b800, 0x0004f800, 0x0004a800, 0x00049800 }, - /* 1 */ - { 0x03a80000, 0x03c00000, 0x03880000, 0x03e80000, - 0x03d00000, 0x03980000, 0x03a00000, 0x03900000, - 0x03f00000, 0x03f80000, 0x03e00000, 0x03b80000, - 0x03b00000, 0x03800000, 0x03c80000, 0x03d80000, - 0x06a80000, 0x06c00000, 0x06880000, 0x06e80000, - 0x06d00000, 0x06980000, 0x06a00000, 0x06900000, - 0x06f00000, 0x06f80000, 0x06e00000, 0x06b80000, - 0x06b00000, 0x06800000, 0x06c80000, 0x06d80000, - 0x05280000, 0x05400000, 0x05080000, 0x05680000, - 0x05500000, 0x05180000, 0x05200000, 0x05100000, - 0x05700000, 0x05780000, 0x05600000, 0x05380000, - 0x05300000, 0x05000000, 0x05480000, 0x05580000, - 0x00a80000, 0x00c00000, 0x00880000, 0x00e80000, - 0x00d00000, 0x00980000, 0x00a00000, 0x00900000, - 0x00f00000, 0x00f80000, 0x00e00000, 0x00b80000, - 0x00b00000, 0x00800000, 0x00c80000, 0x00d80000, - 0x00280000, 0x00400000, 0x00080000, 0x00680000, - 0x00500000, 0x00180000, 0x00200000, 0x00100000, - 0x00700000, 0x00780000, 0x00600000, 0x00380000, - 0x00300000, 0x00000000, 0x00480000, 0x00580000, - 0x04280000, 0x04400000, 0x04080000, 0x04680000, - 0x04500000, 0x04180000, 0x04200000, 0x04100000, - 0x04700000, 0x04780000, 0x04600000, 0x04380000, - 0x04300000, 0x04000000, 0x04480000, 0x04580000, - 0x04a80000, 0x04c00000, 0x04880000, 0x04e80000, - 0x04d00000, 0x04980000, 0x04a00000, 0x04900000, - 0x04f00000, 0x04f80000, 0x04e00000, 0x04b80000, - 0x04b00000, 0x04800000, 0x04c80000, 0x04d80000, - 0x07a80000, 0x07c00000, 0x07880000, 0x07e80000, - 0x07d00000, 0x07980000, 0x07a00000, 0x07900000, - 0x07f00000, 0x07f80000, 0x07e00000, 0x07b80000, - 0x07b00000, 0x07800000, 0x07c80000, 0x07d80000, - 0x07280000, 0x07400000, 0x07080000, 0x07680000, - 0x07500000, 0x07180000, 0x07200000, 0x07100000, - 0x07700000, 0x07780000, 0x07600000, 0x07380000, - 0x07300000, 0x07000000, 0x07480000, 0x07580000, - 0x02280000, 0x02400000, 0x02080000, 0x02680000, - 0x02500000, 0x02180000, 0x02200000, 0x02100000, - 0x02700000, 0x02780000, 0x02600000, 0x02380000, - 0x02300000, 0x02000000, 0x02480000, 0x02580000, - 0x03280000, 0x03400000, 0x03080000, 0x03680000, - 0x03500000, 0x03180000, 0x03200000, 0x03100000, - 0x03700000, 0x03780000, 0x03600000, 0x03380000, - 0x03300000, 0x03000000, 0x03480000, 0x03580000, - 0x06280000, 0x06400000, 0x06080000, 0x06680000, - 0x06500000, 0x06180000, 0x06200000, 0x06100000, - 0x06700000, 0x06780000, 0x06600000, 0x06380000, - 0x06300000, 0x06000000, 0x06480000, 0x06580000, - 0x05a80000, 0x05c00000, 0x05880000, 0x05e80000, - 0x05d00000, 0x05980000, 0x05a00000, 0x05900000, - 0x05f00000, 0x05f80000, 0x05e00000, 0x05b80000, - 0x05b00000, 0x05800000, 0x05c80000, 0x05d80000, - 0x01280000, 0x01400000, 0x01080000, 0x01680000, - 0x01500000, 0x01180000, 0x01200000, 0x01100000, - 0x01700000, 0x01780000, 0x01600000, 0x01380000, - 0x01300000, 0x01000000, 0x01480000, 0x01580000, - 0x02a80000, 0x02c00000, 0x02880000, 0x02e80000, - 0x02d00000, 0x02980000, 0x02a00000, 0x02900000, - 0x02f00000, 0x02f80000, 0x02e00000, 0x02b80000, - 0x02b00000, 0x02800000, 0x02c80000, 0x02d80000, - 0x01a80000, 0x01c00000, 0x01880000, 0x01e80000, - 0x01d00000, 0x01980000, 0x01a00000, 0x01900000, - 0x01f00000, 0x01f80000, 0x01e00000, 0x01b80000, - 0x01b00000, 0x01800000, 0x01c80000, 0x01d80000 }, - /* 2 */ - { 0x30000002, 0x60000002, 0x38000002, 0x08000002, - 0x28000002, 0x78000002, 0x68000002, 0x40000002, - 0x20000002, 0x50000002, 0x48000002, 0x70000002, - 0x00000002, 0x18000002, 0x58000002, 0x10000002, - 0xb0000005, 0xe0000005, 0xb8000005, 0x88000005, - 0xa8000005, 0xf8000005, 0xe8000005, 0xc0000005, - 0xa0000005, 0xd0000005, 0xc8000005, 0xf0000005, - 0x80000005, 0x98000005, 0xd8000005, 0x90000005, - 0x30000005, 0x60000005, 0x38000005, 0x08000005, - 0x28000005, 0x78000005, 0x68000005, 0x40000005, - 0x20000005, 0x50000005, 0x48000005, 0x70000005, - 0x00000005, 0x18000005, 0x58000005, 0x10000005, - 0x30000000, 0x60000000, 0x38000000, 0x08000000, - 0x28000000, 0x78000000, 0x68000000, 0x40000000, - 0x20000000, 0x50000000, 0x48000000, 0x70000000, - 0x00000000, 0x18000000, 0x58000000, 0x10000000, - 0xb0000003, 0xe0000003, 0xb8000003, 0x88000003, - 0xa8000003, 0xf8000003, 0xe8000003, 0xc0000003, - 0xa0000003, 0xd0000003, 0xc8000003, 0xf0000003, - 0x80000003, 0x98000003, 0xd8000003, 0x90000003, - 0x30000001, 0x60000001, 0x38000001, 0x08000001, - 0x28000001, 0x78000001, 0x68000001, 0x40000001, - 0x20000001, 0x50000001, 0x48000001, 0x70000001, - 0x00000001, 0x18000001, 0x58000001, 0x10000001, - 0xb0000000, 0xe0000000, 0xb8000000, 0x88000000, - 0xa8000000, 0xf8000000, 0xe8000000, 0xc0000000, - 0xa0000000, 0xd0000000, 0xc8000000, 0xf0000000, - 0x80000000, 0x98000000, 0xd8000000, 0x90000000, - 0xb0000006, 0xe0000006, 0xb8000006, 0x88000006, - 0xa8000006, 0xf8000006, 0xe8000006, 0xc0000006, - 0xa0000006, 0xd0000006, 0xc8000006, 0xf0000006, - 0x80000006, 0x98000006, 0xd8000006, 0x90000006, - 0xb0000001, 0xe0000001, 0xb8000001, 0x88000001, - 0xa8000001, 0xf8000001, 0xe8000001, 0xc0000001, - 0xa0000001, 0xd0000001, 0xc8000001, 0xf0000001, - 0x80000001, 0x98000001, 0xd8000001, 0x90000001, - 0x30000003, 0x60000003, 0x38000003, 0x08000003, - 0x28000003, 0x78000003, 0x68000003, 0x40000003, - 0x20000003, 0x50000003, 0x48000003, 0x70000003, - 0x00000003, 0x18000003, 0x58000003, 0x10000003, - 0x30000004, 0x60000004, 0x38000004, 0x08000004, - 0x28000004, 0x78000004, 0x68000004, 0x40000004, - 0x20000004, 0x50000004, 0x48000004, 0x70000004, - 0x00000004, 0x18000004, 0x58000004, 0x10000004, - 0xb0000002, 0xe0000002, 0xb8000002, 0x88000002, - 0xa8000002, 0xf8000002, 0xe8000002, 0xc0000002, - 0xa0000002, 0xd0000002, 0xc8000002, 0xf0000002, - 0x80000002, 0x98000002, 0xd8000002, 0x90000002, - 0xb0000004, 0xe0000004, 0xb8000004, 0x88000004, - 0xa8000004, 0xf8000004, 0xe8000004, 0xc0000004, - 0xa0000004, 0xd0000004, 0xc8000004, 0xf0000004, - 0x80000004, 0x98000004, 0xd8000004, 0x90000004, - 0x30000006, 0x60000006, 0x38000006, 0x08000006, - 0x28000006, 0x78000006, 0x68000006, 0x40000006, - 0x20000006, 0x50000006, 0x48000006, 0x70000006, - 0x00000006, 0x18000006, 0x58000006, 0x10000006, - 0xb0000007, 0xe0000007, 0xb8000007, 0x88000007, - 0xa8000007, 0xf8000007, 0xe8000007, 0xc0000007, - 0xa0000007, 0xd0000007, 0xc8000007, 0xf0000007, - 0x80000007, 0x98000007, 0xd8000007, 0x90000007, - 0x30000007, 0x60000007, 0x38000007, 0x08000007, - 0x28000007, 0x78000007, 0x68000007, 0x40000007, - 0x20000007, 0x50000007, 0x48000007, 0x70000007, - 0x00000007, 0x18000007, 0x58000007, 0x10000007 }, - /* 3 */ - { 0x000000e8, 0x000000d8, 0x000000a0, 0x00000088, - 0x00000098, 0x000000f8, 0x000000a8, 0x000000c8, - 0x00000080, 0x000000d0, 0x000000f0, 0x000000b8, - 0x000000b0, 0x000000c0, 0x00000090, 0x000000e0, - 0x000007e8, 0x000007d8, 0x000007a0, 0x00000788, - 0x00000798, 0x000007f8, 0x000007a8, 0x000007c8, - 0x00000780, 0x000007d0, 0x000007f0, 0x000007b8, - 0x000007b0, 0x000007c0, 0x00000790, 0x000007e0, - 0x000006e8, 0x000006d8, 0x000006a0, 0x00000688, - 0x00000698, 0x000006f8, 0x000006a8, 0x000006c8, - 0x00000680, 0x000006d0, 0x000006f0, 0x000006b8, - 0x000006b0, 0x000006c0, 0x00000690, 0x000006e0, - 0x00000068, 0x00000058, 0x00000020, 0x00000008, - 0x00000018, 0x00000078, 0x00000028, 0x00000048, - 0x00000000, 0x00000050, 0x00000070, 0x00000038, - 0x00000030, 0x00000040, 0x00000010, 0x00000060, - 0x000002e8, 0x000002d8, 0x000002a0, 0x00000288, - 0x00000298, 0x000002f8, 0x000002a8, 0x000002c8, - 0x00000280, 0x000002d0, 0x000002f0, 0x000002b8, - 0x000002b0, 0x000002c0, 0x00000290, 0x000002e0, - 0x000003e8, 0x000003d8, 0x000003a0, 0x00000388, - 0x00000398, 0x000003f8, 0x000003a8, 0x000003c8, - 0x00000380, 0x000003d0, 0x000003f0, 0x000003b8, - 0x000003b0, 0x000003c0, 0x00000390, 0x000003e0, - 0x00000568, 0x00000558, 0x00000520, 0x00000508, - 0x00000518, 0x00000578, 0x00000528, 0x00000548, - 0x00000500, 0x00000550, 0x00000570, 0x00000538, - 0x00000530, 0x00000540, 0x00000510, 0x00000560, - 0x00000268, 0x00000258, 0x00000220, 0x00000208, - 0x00000218, 0x00000278, 0x00000228, 0x00000248, - 0x00000200, 0x00000250, 0x00000270, 0x00000238, - 0x00000230, 0x00000240, 0x00000210, 0x00000260, - 0x000004e8, 0x000004d8, 0x000004a0, 0x00000488, - 0x00000498, 0x000004f8, 0x000004a8, 0x000004c8, - 0x00000480, 0x000004d0, 0x000004f0, 0x000004b8, - 0x000004b0, 0x000004c0, 0x00000490, 0x000004e0, - 0x00000168, 0x00000158, 0x00000120, 0x00000108, - 0x00000118, 0x00000178, 0x00000128, 0x00000148, - 0x00000100, 0x00000150, 0x00000170, 0x00000138, - 0x00000130, 0x00000140, 0x00000110, 0x00000160, - 0x000001e8, 0x000001d8, 0x000001a0, 0x00000188, - 0x00000198, 0x000001f8, 0x000001a8, 0x000001c8, - 0x00000180, 0x000001d0, 0x000001f0, 0x000001b8, - 0x000001b0, 0x000001c0, 0x00000190, 0x000001e0, - 0x00000768, 0x00000758, 0x00000720, 0x00000708, - 0x00000718, 0x00000778, 0x00000728, 0x00000748, - 0x00000700, 0x00000750, 0x00000770, 0x00000738, - 0x00000730, 0x00000740, 0x00000710, 0x00000760, - 0x00000368, 0x00000358, 0x00000320, 0x00000308, - 0x00000318, 0x00000378, 0x00000328, 0x00000348, - 0x00000300, 0x00000350, 0x00000370, 0x00000338, - 0x00000330, 0x00000340, 0x00000310, 0x00000360, - 0x000005e8, 0x000005d8, 0x000005a0, 0x00000588, - 0x00000598, 0x000005f8, 0x000005a8, 0x000005c8, - 0x00000580, 0x000005d0, 0x000005f0, 0x000005b8, - 0x000005b0, 0x000005c0, 0x00000590, 0x000005e0, - 0x00000468, 0x00000458, 0x00000420, 0x00000408, - 0x00000418, 0x00000478, 0x00000428, 0x00000448, - 0x00000400, 0x00000450, 0x00000470, 0x00000438, - 0x00000430, 0x00000440, 0x00000410, 0x00000460, - 0x00000668, 0x00000658, 0x00000620, 0x00000608, - 0x00000618, 0x00000678, 0x00000628, 0x00000648, - 0x00000600, 0x00000650, 0x00000670, 0x00000638, - 0x00000630, 0x00000640, 0x00000610, 0x00000660 } -}; - #include "gost.h" +#include "gost-sb.h" static gcry_err_code_t gost_setkey (void *c, const byte *key, unsigned keylen) @@ -315,6 +46,9 @@ gost_setkey (void *c, const byte *key, unsigned keylen) if (keylen != 256 / 8) return GPG_ERR_INV_KEYLEN; + if (!ctx->sbox) + ctx->sbox = sbox_test_3411; + for (i = 0; i < 8; i++) { ctx->key[i] = (key[4 * i + 3] << 24) | @@ -329,10 +63,10 @@ static u32 gost_val (GOST28147_context *ctx, u32 cm1, int subkey) { cm1 += ctx->key[subkey]; - cm1 = test_sbox[0][ (cm1 >> 0) & 0xff] | - test_sbox[1][ (cm1 >> 8) & 0xff] | - test_sbox[2][ (cm1 >> 16) & 0xff] | - test_sbox[3][ (cm1 >> 24) & 0xff]; + cm1 = ctx->sbox[0*256 + ((cm1 >> 0) & 0xff)] | + ctx->sbox[1*256 + ((cm1 >> 8) & 0xff)] | + ctx->sbox[2*256 + ((cm1 >> 16) & 0xff)] | + ctx->sbox[3*256 + ((cm1 >> 24) & 0xff)]; return cm1; } -- 2.0.0.rc2 From dbaryshkov at gmail.com Fri Jun 6 20:48:31 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Fri, 6 Jun 2014 22:48:31 +0400 Subject: [PATCH 05/10] gost28147: support GCRYCTL_SET_SBOX In-Reply-To: <1402080516-8098-1-git-send-email-dbaryshkov@gmail.com> References: <1402080516-8098-1-git-send-email-dbaryshkov@gmail.com> Message-ID: <1402080516-8098-6-git-send-email-dbaryshkov@gmail.com> cipher/gost28147.c (gost_set_extra_info, gost_set_sbox): New. Signed-off-by: Dmitry Eremin-Solenikov --- cipher/gost28147.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/cipher/gost28147.c b/cipher/gost28147.c index 1720f45..52d0946 100644 --- a/cipher/gost28147.c +++ b/cipher/gost28147.c @@ -175,6 +175,43 @@ gost_decrypt_block (void *c, byte *outbuf, const byte *inbuf) 4*sizeof(void*) /* gost_val call */; } +static gpg_err_code_t gost_set_sbox (GOST28147_context *ctx, const char *oid) +{ + int i; + + for (i = 0; gost_oid_map[i].oid; i++) + { + if (!strcmp(gost_oid_map[i].oid, oid)) + { + ctx->sbox = gost_oid_map[i].sbox; + return 0; + } + } + return GPG_ERR_VALUE_NOT_FOUND; +} + +static gpg_err_code_t +gost_set_extra_info (void *c, int what, const void *buffer, size_t buflen) +{ + GOST28147_context *ctx = c; + gpg_err_code_t ec = 0; + + (void)buffer; + (void)buflen; + + switch (what) + { + case GCRYCTL_SET_SBOX: + ec = gost_set_sbox (ctx, buffer); + break; + + default: + ec = GPG_ERR_INV_OP; + break; + } + return ec; +} + static gcry_cipher_oid_spec_t oids_gost28147[] = { /* { "1.2.643.2.2.31.0", GCRY_CIPHER_MODE_CNTGOST }, */ @@ -193,4 +230,5 @@ gcry_cipher_spec_t _gcry_cipher_spec_gost28147 = gost_setkey, gost_encrypt_block, gost_decrypt_block, + NULL, NULL, NULL, gost_set_extra_info, }; -- 2.0.0.rc2 From dbaryshkov at gmail.com Fri Jun 6 20:48:27 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Fri, 6 Jun 2014 22:48:27 +0400 Subject: [PATCH] Stribog endianness fixup In-Reply-To: <1402080516-8098-1-git-send-email-dbaryshkov@gmail.com> References: <1402080516-8098-1-git-send-email-dbaryshkov@gmail.com> Message-ID: <1402080516-8098-2-git-send-email-dbaryshkov@gmail.com> Signed-off-by: Dmitry Eremin-Solenikov --- cipher/gost28147.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++ cipher/mac-internal.h | 9 ++++ cipher/mac.c | 3 ++ cipher/stribog.c | 10 ++-- src/gcrypt.h.in | 1 + tests/basic.c | 7 +++ 6 files changed, 155 insertions(+), 5 deletions(-) diff --git a/cipher/stribog.c b/cipher/stribog.c index 1456fee..fa16cfe 100644 --- a/cipher/stribog.c +++ b/cipher/stribog.c @@ -1242,12 +1242,12 @@ transform_bits (STRIBOG_CONTEXT *hd, const unsigned char *data, unsigned count) } } - hd->Sigma[0] += M[0]; - for (i = 1; i < 8; i++) - if (hd->Sigma[i-1] < M[i-1]) - hd->Sigma[i] += M[i] + 1; + hd->Sigma[7] += M[7]; + for (i = 7; i >= 1; i--) + if (hd->Sigma[i] < M[i]) + hd->Sigma[i-1] += M[i-1] + 1; else - hd->Sigma[i] += M[i]; + hd->Sigma[i-1] += M[i-1]; } static unsigned int From dbaryshkov at gmail.com Fri Jun 6 20:48:30 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Fri, 6 Jun 2014 22:48:30 +0400 Subject: [PATCH 04/10] Support setting s-box for the ciphers that require it In-Reply-To: <1402080516-8098-1-git-send-email-dbaryshkov@gmail.com> References: <1402080516-8098-1-git-send-email-dbaryshkov@gmail.com> Message-ID: <1402080516-8098-5-git-send-email-dbaryshkov@gmail.com> * src/gcrypt.h.in (GCRYCTL_SET_SBOX, gcry_cipher_set_sbox): New. * cipher/cipher.c (_gcry_cipher_ctl): pass GCRYCTL_SET_SBOX to set_extra_info callback. Signed-off-by: Dmitry Eremin-Solenikov --- cipher/cipher.c | 7 +++++++ src/gcrypt.h.in | 6 +++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/cipher/cipher.c b/cipher/cipher.c index da59061..5c44c0d 100644 --- a/cipher/cipher.c +++ b/cipher/cipher.c @@ -1264,6 +1264,13 @@ _gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen) } break; + case GCRYCTL_SET_SBOX: + if (h->spec->set_extra_info) + rc = h->spec->set_extra_info + (&h->context.c, GCRYCTL_SET_SBOX, buffer, buflen); + else + rc = GPG_ERR_NOT_SUPPORTED; + default: rc = GPG_ERR_INV_OP; } diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index bd38a24..95d324b 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -329,7 +329,8 @@ enum gcry_ctl_cmds GCRYCTL_SET_CCM_LENGTHS = 69, GCRYCTL_CLOSE_RANDOM_DEVICE = 70, GCRYCTL_INACTIVATE_FIPS_FLAG = 71, - GCRYCTL_REACTIVATE_FIPS_FLAG = 72 + GCRYCTL_REACTIVATE_FIPS_FLAG = 72, + GCRYCTL_SET_SBOX = 73 }; /* Perform various operations defined by CMD. */ @@ -1002,6 +1003,9 @@ gcry_error_t gcry_cipher_checktag (gcry_cipher_hd_t hd, const void *intag, #define gcry_cipher_cts(h,on) gcry_cipher_ctl( (h), GCRYCTL_SET_CBC_CTS, \ NULL, on ) +#define gcry_cipher_set_sbox(h,oid) gcry_cipher_ctl( (h), GCRYCTL_SET_SBOX, \ + (oid), 0); + /* Set counter for CTR mode. (CTR,CTRLEN) must denote a buffer of block size length, or (NULL,0) to set the CTR to the all-zero block. */ gpg_error_t gcry_cipher_setctr (gcry_cipher_hd_t hd, -- 2.0.0.rc2 From dbaryshkov at gmail.com Fri Jun 6 20:48:28 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Fri, 6 Jun 2014 22:48:28 +0400 Subject: [PATCH 02/10] gost28147: add OIDs used to define cipher mode In-Reply-To: <1402080516-8098-1-git-send-email-dbaryshkov@gmail.com> References: <1402080516-8098-1-git-send-email-dbaryshkov@gmail.com> Message-ID: <1402080516-8098-3-git-send-email-dbaryshkov@gmail.com> * cipher/gost28147 (oids_gost28147): Add OID from RFC4357. Signed-off-by: Dmitry Eremin-Solenikov --- cipher/gost28147.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/cipher/gost28147.c b/cipher/gost28147.c index c094209..1e48eb0 100644 --- a/cipher/gost28147.c +++ b/cipher/gost28147.c @@ -441,10 +441,20 @@ gost_decrypt_block (void *c, byte *outbuf, const byte *inbuf) 4*sizeof(void*) /* gost_val call */; } +static gcry_cipher_oid_spec_t oids_gost28147[] = + { + /* { "1.2.643.2.2.31.0", GCRY_CIPHER_MODE_CNTGOST }, */ + { "1.2.643.2.2.31.1", GCRY_CIPHER_MODE_CFB }, + { "1.2.643.2.2.31.2", GCRY_CIPHER_MODE_CFB }, + { "1.2.643.2.2.31.3", GCRY_CIPHER_MODE_CFB }, + { "1.2.643.2.2.31.4", GCRY_CIPHER_MODE_CFB }, + { NULL } + }; + gcry_cipher_spec_t _gcry_cipher_spec_gost28147 = { GCRY_CIPHER_GOST28147, {0, 0}, - "GOST28147", NULL, NULL, 8, 256, + "GOST28147", NULL, oids_gost28147, 8, 256, sizeof (GOST28147_context), gost_setkey, gost_encrypt_block, -- 2.0.0.rc2 From rezakarimi66 at gmail.com Sat Jun 7 17:32:27 2014 From: rezakarimi66 at gmail.com (Reza Karimi) Date: Sat, 7 Jun 2014 20:02:27 +0430 Subject: Adding libgcrpyt to Network Simulator 2 (NS2) Message-ID: <000701cf8265$b35e6750$1a1b35f0$@gmail.com> Hi I am going to use "libgcrypt" in Network Simulator 2 (NS2), but I don't know how. Any help or example will be so appreciated. Thanks in advance for your help. ______________________________________________________ Reza Karimi, M.Sc. Faculty of Electrical and Computer Engineering (ECE) K.N.Toosi University of Technology Tehran, IRAN. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bradh at frogmouth.net Sun Jun 8 06:45:47 2014 From: bradh at frogmouth.net (Brad Hards) Date: Sun, 08 Jun 2014 14:45:47 +1000 Subject: Adding libgcrpyt to Network Simulator 2 (NS2) In-Reply-To: <000701cf8265$b35e6750$1a1b35f0$@gmail.com> References: <000701cf8265$b35e6750$1a1b35f0$@gmail.com> Message-ID: <1445974.XLogUEyzGd@saxicola> On Sat, 7 Jun 2014 08:02:27 PM Reza Karimi wrote: > I am going to use "libgcrypt" in Network Simulator 2 (NS2), but I don't know > how. Any help or example will be so appreciated. It isn't clear how NS2 and libgcrypt (or another low level crypto library) are related. Perhaps you can describe what you are trying to achieve, what you've already tried, and what the results of that were. http://www.catb.org/esr/faqs/smart-questions.html might also help. Brad From jussi.kivilinna at iki.fi Wed Jun 11 18:44:12 2014 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Wed, 11 Jun 2014 19:44:12 +0300 Subject: [PATCH] Poly1305-AEAD: update to match latest Internet-Draft version Message-ID: <20140611164412.19049.99544.stgit@localhost6.localdomain6> * cipher/cipher-internal.h (gcry_cipher_handle): Use separate byte counters for AAD and data in Poly1305. * cipher/cipher-poly1305.c (poly1305_fill_bytecount): Remove. (poly1305_fill_bytecounts, poly1305_do_padding): New. (poly1305_aad_finish): Fill padding to Poly1305 and do not fill AAD length. (_gcry_cipher_poly1305_authenticate, _gcry_cipher_poly1305_encrypt) (_gcry_cipher_poly1305_decrypt): Update AAD and data length separately. (_gcry_cipher_poly1305_tag): Fill padding and bytecounts to Poly1305. (_gcry_cipher_poly1305_setkey, _gcry_cipher_poly1305_setiv): Reset AAD and data byte counts. * tests/basic.c (_check_poly1305_cipher): Update test-vectors. -- New Internet-Draft version for "ChaCha20 and Poly1305 for IETF protocols" added padding to Poly1305-AEAD: http://tools.ietf.org/rfcdiff?url2=draft-nir-cfrg-chacha20-poly1305-04.txt Patch makes Poly1305-AEAD implementation to match the changes. Signed-off-by: Jussi Kivilinna --- cipher/cipher-internal.h | 7 +++-- cipher/cipher-poly1305.c | 63 ++++++++++++++++++++++++++++++++------------ tests/basic.c | 66 ++++++++++++++++++++++++++++++++++------------ 3 files changed, 100 insertions(+), 36 deletions(-) diff --git a/cipher/cipher-internal.h b/cipher/cipher-internal.h index f6bda66..0e73fde 100644 --- a/cipher/cipher-internal.h +++ b/cipher/cipher-internal.h @@ -159,8 +159,11 @@ struct gcry_cipher_handle /* Mode specific storage for Poly1305 mode. */ struct { - /* byte counter for AAD and data. */ - u32 bytecount[2]; + /* byte counter for AAD. */ + u32 aadcount[2]; + + /* byte counter for data. */ + u32 datacount[2]; unsigned int aad_finalized:1; unsigned int bytecount_over_limits:1; diff --git a/cipher/cipher-poly1305.c b/cipher/cipher-poly1305.c index a22ffa3..e9e063d 100644 --- a/cipher/cipher-poly1305.c +++ b/cipher/cipher-poly1305.c @@ -53,12 +53,14 @@ poly1305_bytecounter_add (u32 ctr[2], size_t add) static void -poly1305_fill_bytecount (gcry_cipher_hd_t c) +poly1305_fill_bytecounts (gcry_cipher_hd_t c) { - u32 lenbuf[2]; + u32 lenbuf[4]; - lenbuf[0] = le_bswap32(c->u_mode.poly1305.bytecount[0]); - lenbuf[1] = le_bswap32(c->u_mode.poly1305.bytecount[1]); + lenbuf[0] = le_bswap32(c->u_mode.poly1305.aadcount[0]); + lenbuf[1] = le_bswap32(c->u_mode.poly1305.aadcount[1]); + lenbuf[2] = le_bswap32(c->u_mode.poly1305.datacount[0]); + lenbuf[3] = le_bswap32(c->u_mode.poly1305.datacount[1]); _gcry_poly1305_update (&c->u_mode.poly1305.ctx, (byte*)lenbuf, sizeof(lenbuf)); @@ -67,15 +69,33 @@ poly1305_fill_bytecount (gcry_cipher_hd_t c) static void +poly1305_do_padding (gcry_cipher_hd_t c, u32 ctr[2]) +{ + static const byte zero_padding_buf[15] = {}; + u32 padding_count; + + /* Padding to 16 byte boundary. */ + if (ctr[0] % 16 > 0) + { + padding_count = 16 - ctr[0] % 16; + + _gcry_poly1305_update (&c->u_mode.poly1305.ctx, zero_padding_buf, + padding_count); + } +} + + +static void poly1305_aad_finish (gcry_cipher_hd_t c) { - /* Start of encryption marks end of AAD stream. */ - poly1305_fill_bytecount(c); + /* After AAD, feed padding bytes so we get 16 byte alignment. */ + poly1305_do_padding (c, c->u_mode.poly1305.aadcount); + /* Start of encryption marks end of AAD stream. */ c->u_mode.poly1305.aad_finalized = 1; - c->u_mode.poly1305.bytecount[0] = 0; - c->u_mode.poly1305.bytecount[1] = 0; + c->u_mode.poly1305.datacount[0] = 0; + c->u_mode.poly1305.datacount[1] = 0; } @@ -102,7 +122,7 @@ _gcry_cipher_poly1305_authenticate (gcry_cipher_hd_t c, if (!c->marks.iv) poly1305_set_zeroiv(c); - if (poly1305_bytecounter_add(c->u_mode.poly1305.bytecount, aadbuflen)) + if (poly1305_bytecounter_add(c->u_mode.poly1305.aadcount, aadbuflen)) { c->u_mode.poly1305.bytecount_over_limits = 1; return GPG_ERR_INV_LENGTH; @@ -138,7 +158,7 @@ _gcry_cipher_poly1305_encrypt (gcry_cipher_hd_t c, if (!c->u_mode.poly1305.aad_finalized) poly1305_aad_finish(c); - if (poly1305_bytecounter_add(c->u_mode.poly1305.bytecount, inbuflen)) + if (poly1305_bytecounter_add(c->u_mode.poly1305.datacount, inbuflen)) { c->u_mode.poly1305.bytecount_over_limits = 1; return GPG_ERR_INV_LENGTH; @@ -176,7 +196,7 @@ _gcry_cipher_poly1305_decrypt (gcry_cipher_hd_t c, if (!c->u_mode.poly1305.aad_finalized) poly1305_aad_finish(c); - if (poly1305_bytecounter_add(c->u_mode.poly1305.bytecount, inbuflen)) + if (poly1305_bytecounter_add(c->u_mode.poly1305.datacount, inbuflen)) { c->u_mode.poly1305.bytecount_over_limits = 1; return GPG_ERR_INV_LENGTH; @@ -212,8 +232,11 @@ _gcry_cipher_poly1305_tag (gcry_cipher_hd_t c, if (!c->marks.tag) { - /* Write data-length to poly1305. */ - poly1305_fill_bytecount(c); + /* After data, feed padding bytes so we get 16 byte alignment. */ + poly1305_do_padding (c, c->u_mode.poly1305.datacount); + + /* Write byte counts to poly1305. */ + poly1305_fill_bytecounts(c); _gcry_poly1305_finish(&c->u_mode.poly1305.ctx, c->u_iv.iv); @@ -247,8 +270,11 @@ _gcry_cipher_poly1305_check_tag (gcry_cipher_hd_t c, const unsigned char *intag, void _gcry_cipher_poly1305_setkey (gcry_cipher_hd_t c) { - c->u_mode.poly1305.bytecount[0] = 0; - c->u_mode.poly1305.bytecount[1] = 0; + c->u_mode.poly1305.aadcount[0] = 0; + c->u_mode.poly1305.aadcount[1] = 0; + + c->u_mode.poly1305.datacount[0] = 0; + c->u_mode.poly1305.datacount[1] = 0; c->u_mode.poly1305.bytecount_over_limits = 0; c->u_mode.poly1305.aad_finalized = 0; @@ -268,8 +294,11 @@ _gcry_cipher_poly1305_setiv (gcry_cipher_hd_t c, const byte *iv, size_t ivlen) memset(&c->u_mode.poly1305.ctx, 0, sizeof(c->u_mode.poly1305.ctx)); - c->u_mode.poly1305.bytecount[0] = 0; - c->u_mode.poly1305.bytecount[1] = 0; + c->u_mode.poly1305.aadcount[0] = 0; + c->u_mode.poly1305.aadcount[1] = 0; + + c->u_mode.poly1305.datacount[0] = 0; + c->u_mode.poly1305.datacount[1] = 0; c->u_mode.poly1305.bytecount_over_limits = 0; c->u_mode.poly1305.aad_finalized = 0; diff --git a/tests/basic.c b/tests/basic.c index 875b36c..bc18aac 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -1625,27 +1625,59 @@ _check_poly1305_cipher (unsigned int step) struct tv { int algo; - char key[MAX_DATA_LEN]; - char iv[MAX_DATA_LEN]; + const char *key; + const char *iv; int ivlen; - unsigned char aad[MAX_DATA_LEN]; + const char *aad; int aadlen; - unsigned char plaintext[MAX_DATA_LEN]; + const char *plaintext; int inlen; - char out[MAX_DATA_LEN]; - char tag[MAX_DATA_LEN]; + const char *out; + const char *tag; } tv[] = { - /* draft-agl-tls-chacha20poly1305-04 */ + /* draft-nir-cfrg-chacha20-poly1305-04 */ { GCRY_CIPHER_CHACHA20, - "\x42\x90\xbc\xb1\x54\x17\x35\x31\xf3\x14\xaf\x57\xf3\xbe\x3b\x50" - "\x06\xda\x37\x1e\xce\x27\x2a\xfa\x1b\x5d\xbd\xd1\x10\x0a\x10\x07", - "\xcd\x7c\xf6\x7b\xe3\x9c\x79\x4a", 8, - "\x87\xe2\x29\xd4\x50\x08\x45\xa0\x79\xc0", 10, - "\x86\xd0\x99\x74\x84\x0b\xde\xd2\xa5\xca", 10, - "\xe3\xe4\x46\xf7\xed\xe9\xa1\x9b\x62\xa4", - "\x67\x7d\xab\xf4\xe3\xd2\x4b\x87\x6b\xb2\x84\x75\x38\x96\xe1\xd6" }, - /* draft-nir-cfrg-chacha20-poly1305-03 */ + "\x1c\x92\x40\xa5\xeb\x55\xd3\x8a\xf3\x33\x88\x86\x04\xf6\xb5\xf0" + "\x47\x39\x17\xc1\x40\x2b\x80\x09\x9d\xca\x5c\xbc\x20\x70\x75\xc0", + "\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08", 12, + "\xf3\x33\x88\x86\x00\x00\x00\x00\x00\x00\x4e\x91", 12, + "\x49\x6e\x74\x65\x72\x6e\x65\x74\x2d\x44\x72\x61\x66\x74\x73\x20" + "\x61\x72\x65\x20\x64\x72\x61\x66\x74\x20\x64\x6f\x63\x75\x6d\x65" + "\x6e\x74\x73\x20\x76\x61\x6c\x69\x64\x20\x66\x6f\x72\x20\x61\x20" + "\x6d\x61\x78\x69\x6d\x75\x6d\x20\x6f\x66\x20\x73\x69\x78\x20\x6d" + "\x6f\x6e\x74\x68\x73\x20\x61\x6e\x64\x20\x6d\x61\x79\x20\x62\x65" + "\x20\x75\x70\x64\x61\x74\x65\x64\x2c\x20\x72\x65\x70\x6c\x61\x63" + "\x65\x64\x2c\x20\x6f\x72\x20\x6f\x62\x73\x6f\x6c\x65\x74\x65\x64" + "\x20\x62\x79\x20\x6f\x74\x68\x65\x72\x20\x64\x6f\x63\x75\x6d\x65" + "\x6e\x74\x73\x20\x61\x74\x20\x61\x6e\x79\x20\x74\x69\x6d\x65\x2e" + "\x20\x49\x74\x20\x69\x73\x20\x69\x6e\x61\x70\x70\x72\x6f\x70\x72" + "\x69\x61\x74\x65\x20\x74\x6f\x20\x75\x73\x65\x20\x49\x6e\x74\x65" + "\x72\x6e\x65\x74\x2d\x44\x72\x61\x66\x74\x73\x20\x61\x73\x20\x72" + "\x65\x66\x65\x72\x65\x6e\x63\x65\x20\x6d\x61\x74\x65\x72\x69\x61" + "\x6c\x20\x6f\x72\x20\x74\x6f\x20\x63\x69\x74\x65\x20\x74\x68\x65" + "\x6d\x20\x6f\x74\x68\x65\x72\x20\x74\x68\x61\x6e\x20\x61\x73\x20" + "\x2f\xe2\x80\x9c\x77\x6f\x72\x6b\x20\x69\x6e\x20\x70\x72\x6f\x67" + "\x72\x65\x73\x73\x2e\x2f\xe2\x80\x9d", 265, + "\x64\xa0\x86\x15\x75\x86\x1a\xf4\x60\xf0\x62\xc7\x9b\xe6\x43\xbd" + "\x5e\x80\x5c\xfd\x34\x5c\xf3\x89\xf1\x08\x67\x0a\xc7\x6c\x8c\xb2" + "\x4c\x6c\xfc\x18\x75\x5d\x43\xee\xa0\x9e\xe9\x4e\x38\x2d\x26\xb0" + "\xbd\xb7\xb7\x3c\x32\x1b\x01\x00\xd4\xf0\x3b\x7f\x35\x58\x94\xcf" + "\x33\x2f\x83\x0e\x71\x0b\x97\xce\x98\xc8\xa8\x4a\xbd\x0b\x94\x81" + "\x14\xad\x17\x6e\x00\x8d\x33\xbd\x60\xf9\x82\xb1\xff\x37\xc8\x55" + "\x97\x97\xa0\x6e\xf4\xf0\xef\x61\xc1\x86\x32\x4e\x2b\x35\x06\x38" + "\x36\x06\x90\x7b\x6a\x7c\x02\xb0\xf9\xf6\x15\x7b\x53\xc8\x67\xe4" + "\xb9\x16\x6c\x76\x7b\x80\x4d\x46\xa5\x9b\x52\x16\xcd\xe7\xa4\xe9" + "\x90\x40\xc5\xa4\x04\x33\x22\x5e\xe2\x82\xa1\xb0\xa0\x6c\x52\x3e" + "\xaf\x45\x34\xd7\xf8\x3f\xa1\x15\x5b\x00\x47\x71\x8c\xbc\x54\x6a" + "\x0d\x07\x2b\x04\xb3\x56\x4e\xea\x1b\x42\x22\x73\xf5\x48\x27\x1a" + "\x0b\xb2\x31\x60\x53\xfa\x76\x99\x19\x55\xeb\xd6\x31\x59\x43\x4e" + "\xce\xbb\x4e\x46\x6d\xae\x5a\x10\x73\xa6\x72\x76\x27\x09\x7a\x10" + "\x49\xe6\x17\xd9\x1d\x36\x10\x94\xfa\x68\xf0\xff\x77\x98\x71\x30" + "\x30\x5b\xea\xba\x2e\xda\x04\xdf\x99\x7b\x71\x4d\x6c\x6f\x2c\x29" + "\xa6\xad\x5c\xb4\x02\x2b\x02\x70\x9b", + "\xee\xad\x9d\x67\x89\x0c\xbb\x22\x39\x23\x36\xfe\xa1\x85\x1f\x38" }, + /* draft-nir-cfrg-chacha20-poly1305-04 */ { GCRY_CIPHER_CHACHA20, "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f", @@ -1661,11 +1693,11 @@ _check_poly1305_cipher (unsigned int step) "\xfa\xb3\x24\xe4\xfa\xd6\x75\x94\x55\x85\x80\x8b\x48\x31\xd7\xbc" "\x3f\xf4\xde\xf0\x8e\x4b\x7a\x9d\xe5\x76\xd2\x65\x86\xce\xc6\x4b" "\x61\x16", - "\x18\xfb\x11\xa5\x03\x1a\xd1\x3a\x7e\x3b\x03\xd4\x6e\xe3\xa6\xa7" } + "\x1a\xe1\x0b\x59\x4f\x09\xe2\x6a\x7e\x90\x2e\xcb\xd0\x60\x06\x91" }, }; gcry_cipher_hd_t hde, hdd; - unsigned char out[MAX_DATA_LEN]; + unsigned char out[1024]; unsigned char tag[16]; int i, keylen; gcry_error_t err = 0; From dbaryshkov at gmail.com Tue Jun 17 13:11:46 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Tue, 17 Jun 2014 15:11:46 +0400 Subject: [PATCH] Stribog endianness fixup In-Reply-To: <1402080516-8098-2-git-send-email-dbaryshkov@gmail.com> References: <1402080516-8098-1-git-send-email-dbaryshkov@gmail.com> <1402080516-8098-2-git-send-email-dbaryshkov@gmail.com> Message-ID: Please ignore this particular patch, it was sent by the coincidence. The rest of the patches still are proposed to be applied. On Fri, Jun 6, 2014 at 10:48 PM, Dmitry Eremin-Solenikov wrote: > Signed-off-by: Dmitry Eremin-Solenikov > --- > cipher/gost28147.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++ > cipher/mac-internal.h | 9 ++++ > cipher/mac.c | 3 ++ > cipher/stribog.c | 10 ++-- > src/gcrypt.h.in | 1 + > tests/basic.c | 7 +++ > 6 files changed, 155 insertions(+), 5 deletions(-) > > diff --git a/cipher/stribog.c b/cipher/stribog.c > index 1456fee..fa16cfe 100644 > --- a/cipher/stribog.c > +++ b/cipher/stribog.c > @@ -1242,12 +1242,12 @@ transform_bits (STRIBOG_CONTEXT *hd, const unsigned char *data, unsigned count) > } > } > > - hd->Sigma[0] += M[0]; > - for (i = 1; i < 8; i++) > - if (hd->Sigma[i-1] < M[i-1]) > - hd->Sigma[i] += M[i] + 1; > + hd->Sigma[7] += M[7]; > + for (i = 7; i >= 1; i--) > + if (hd->Sigma[i] < M[i]) > + hd->Sigma[i-1] += M[i-1] + 1; > else > - hd->Sigma[i] += M[i]; > + hd->Sigma[i-1] += M[i-1]; > } > > static unsigned int -- With best wishes Dmitry From gniibe at fsij.org Thu Jun 19 07:58:35 2014 From: gniibe at fsij.org (NIIBE Yutaka) Date: Thu, 19 Jun 2014 14:58:35 +0900 Subject: [PATCH] Curve25519 patch revised Message-ID: <1403157515.2821.8.camel@cfw2.gniibe.org> Hello, Here is a revised patch for Curve25519 support. With mpi_swap_conditional, it's getting to constant-time. diff --git a/cipher/ecc-curves.c b/cipher/ecc-curves.c index 0f622f7..e7dbc17 100644 --- a/cipher/ecc-curves.c +++ b/cipher/ecc-curves.c @@ -40,7 +40,7 @@ static const struct const char *other; /* Other name. */ } curve_aliases[] = { - /*{ "Curve25519", "1.3.6.1.4.1.3029.1.5.1" },*/ + { "Curve25519", "1.3.6.1.4.1.3029.1.5.1" }, { "Ed25519", "1.3.6.1.4.1.11591.15.1" }, { "NIST P-192", "1.2.840.10045.3.1.1" }, /* X9.62 OID */ @@ -127,6 +127,17 @@ static const ecc_domain_parms_t domain_parms[] = "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A", "0x6666666666666666666666666666666666666666666666666666666666666658" }, + { + /* (y^2 = x^3 + 486662*x^2 + x) */ + "Curve25519", 256, 0, + MPI_EC_MONTGOMERY, ECC_DIALECT_STANDARD, + "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED", + "0x01DB41", + "0x01", + "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", + "0x0000000000000000000000000000000000000000000000000000000000000009", + "0x20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9" + }, #if 0 /* No real specs yet found. */ { /* x^2 + y^2 = 1 + 3617x^2y^2 mod 2^414 - 17 */ @@ -507,9 +518,8 @@ _gcry_ecc_fill_in_curve (unsigned int nbits, const char *name, { case MPI_EC_WEIERSTRASS: case MPI_EC_EDWARDS: - break; case MPI_EC_MONTGOMERY: - return GPG_ERR_NOT_SUPPORTED; + break; default: return GPG_ERR_BUG; } diff --git a/cipher/ecc-misc.c b/cipher/ecc-misc.c index 3f284fe..595aa0c 100644 --- a/cipher/ecc-misc.c +++ b/cipher/ecc-misc.c @@ -202,8 +202,13 @@ _gcry_ecc_os2ec (mpi_point_t result, gcry_mpi_t value) } if (*buf != 4) { + /* x-coordinate only */ + mpi_set (result->x, value); + mpi_clear (result->y); + mpi_set_ui (result->z, 1); + xfree (buf_memory); - return GPG_ERR_NOT_IMPLEMENTED; /* No support for point compression. */ + return 0; } if ( ((n-1)%2) ) { diff --git a/cipher/ecc.c b/cipher/ecc.c index e0be2d4..6a60785 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -117,7 +117,25 @@ nist_generate_key (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx, point_init (&Q); /* Generate a secret. */ - if (ctx->dialect == ECC_DIALECT_ED25519) + /* + * FIXME. It should be something like this: + * + * When the co-factor of the curve is not 1, we guarantee that + * scalar value k is multiple of its co-factor to avoid sub-group + * attack. Also, we make sure that the most significant bit of k + * is 1. + * + * It works for now as we only have two curves which have co-factor!=1; + * Ed25519 and Curve25519. + * Note that we need some a way to get number of bits of the curve to + * set MSB of k. Currently, E.nbits is not precise for this purpuse. + * We also need a way to get co-factor of a curve. + * + * Currently, we distinguish the two curves by ECC_DIALECT_ED25519 + * and MPI_EC_MONTGOMERY, which works, but is not that correct. + */ + if (ctx->dialect == ECC_DIALECT_ED25519 + || E->model == MPI_EC_MONTGOMERY) { char *rndbuf; @@ -156,7 +174,7 @@ nist_generate_key (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx, * possibilities without any loss of security. Note that we don't * do that for Ed25519 so that we do not violate the special * construction of the secret key. */ - if (E->dialect == ECC_DIALECT_ED25519) + if (E->dialect == ECC_DIALECT_ED25519 || E->model == MPI_EC_MONTGOMERY) point_set (&sk->Q, &Q); else { @@ -227,12 +245,8 @@ static void test_keys (ECC_secret_key *sk, unsigned int nbits) { ECC_public_key pk; - gcry_mpi_t test = mpi_new (nbits); + gcry_mpi_t test; mpi_point_struct R_; - gcry_mpi_t c = mpi_new (nbits); - gcry_mpi_t out = mpi_new (nbits); - gcry_mpi_t r = mpi_new (nbits); - gcry_mpi_t s = mpi_new (nbits); if (DBG_CIPHER) log_debug ("Testing key.\n"); @@ -243,27 +257,82 @@ test_keys (ECC_secret_key *sk, unsigned int nbits) point_init (&pk.Q); point_set (&pk.Q, &sk->Q); - _gcry_mpi_randomize (test, nbits, GCRY_WEAK_RANDOM); + if (sk->E.model == MPI_EC_MONTGOMERY) + /* It's ECDH only. */ + /* FIXME: see the FIXME comment of nist_generate_key. + * Here, we generate ephemeral key, same handling is needed for secret. + */ + { + char *rndbuf; + gcry_mpi_t x0, x1; + mpi_ec_t ec; + + test = mpi_new (256); + rndbuf = _gcry_random_bytes (32, GCRY_WEAK_RANDOM); + rndbuf[0] &= 0x7f; /* Clear bit 255. */ + rndbuf[0] |= 0x40; /* Set bit 254. */ + rndbuf[31] &= 0xf8; /* Clear bits 2..0 so that d mod 8 == 0 */ + _gcry_mpi_set_buffer (test, rndbuf, 32, 0); + xfree (rndbuf); + + ec = _gcry_mpi_ec_p_internal_new (pk.E.model, pk.E.dialect, 0, + pk.E.p, pk.E.a, pk.E.b); + x0 = mpi_new (0); + x1 = mpi_new (0); - if (_gcry_ecc_ecdsa_sign (test, sk, r, s, 0, 0) ) - log_fatal ("ECDSA operation: sign failed\n"); + /* R_ = kQ <=> R_ = kdG */ + _gcry_mpi_ec_mul_point (&R_, test, &pk.Q, ec); + if (_gcry_mpi_ec_get_affine (x0, NULL, &R_, ec)) + log_fatal ("ecdh: Failed to get affine coordinates for kQ\n"); - if (_gcry_ecc_ecdsa_verify (test, &pk, r, s)) - { - log_fatal ("ECDSA operation: sign, verify failed\n"); + /* R_ = kG */ + _gcry_mpi_ec_mul_point (&R_, test, &pk.E.G, ec); + /* R_ = dkG */ + _gcry_mpi_ec_mul_point (&R_, sk->d, &R_, ec); + + if (_gcry_mpi_ec_get_affine (x1, NULL, &R_, ec)) + log_fatal ("ecdh: Failed to get affine coordinates for dkG\n"); + + if (mpi_cmp (x0, x1)) + { + log_fatal ("ECDH test failed.\n"); + } + + mpi_free (x0); + mpi_free (x1); + _gcry_mpi_ec_free (ec); } + else + { + gcry_mpi_t c = mpi_new (nbits); + gcry_mpi_t out = mpi_new (nbits); + gcry_mpi_t r = mpi_new (nbits); + gcry_mpi_t s = mpi_new (nbits); - if (DBG_CIPHER) - log_debug ("ECDSA operation: sign, verify ok.\n"); + test = mpi_new (nbits); + _gcry_mpi_randomize (test, nbits, GCRY_WEAK_RANDOM); + + if (_gcry_ecc_ecdsa_sign (test, sk, r, s, 0, 0) ) + log_fatal ("ECDSA operation: sign failed\n"); + + if (_gcry_ecc_ecdsa_verify (test, &pk, r, s)) + { + log_fatal ("ECDSA operation: sign, verify failed\n"); + } + + if (DBG_CIPHER) + log_debug ("ECDSA operation: sign, verify ok.\n"); + + mpi_free (s); + mpi_free (r); + mpi_free (out); + mpi_free (c); + } point_free (&pk.Q); _gcry_ecc_curve_free (&pk.E); point_free (&R_); - mpi_free (s); - mpi_free (r); - mpi_free (out); - mpi_free (c); mpi_free (test); } diff --git a/mpi/ec.c b/mpi/ec.c index 4f35de0..f2dd0f0 100644 --- a/mpi/ec.c +++ b/mpi/ec.c @@ -600,10 +600,13 @@ _gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t point, case MPI_EC_MONTGOMERY: { - log_fatal ("%s: %s not yet supported\n", - "_gcry_mpi_ec_get_affine", "Montgomery"); + if (x) + mpi_set (x, point->x); + + if (y) + mpi_set (y, point->y); } - return -1; + return 0; case MPI_EC_EDWARDS: { @@ -1073,6 +1076,35 @@ add_points_edwards (mpi_point_t result, } +/* PRD = 2 * P1. + SUM = P1 + P2. + P1 - P2 = DIF */ +static void +dup_and_add_montgomery (mpi_point_t prd, mpi_point_t sum, + mpi_point_t p1, mpi_point_t p2, gcry_mpi_t dif_x, + mpi_ec_t ctx) +{ + ec_addm (sum->x, p2->x, p2->z, ctx); + ec_subm (p2->z, p2->x, p2->z, ctx); + ec_addm (prd->x, p1->x, p1->z, ctx); + ec_subm (p1->z, p1->x, p1->z, ctx); + ec_mulm (p2->x, p1->z, sum->x, ctx); + ec_mulm (p2->z, prd->x, p2->z, ctx); + ec_pow2 (p1->x, prd->x, ctx); + ec_pow2 (p1->z, p1->z, ctx); + ec_addm (sum->x, p2->x, p2->z, ctx); + ec_subm (p2->z, p2->x, p2->z, ctx); + ec_mulm (prd->x, p1->x, p1->z, ctx); + ec_subm (p1->z, p1->x, p1->z, ctx); + ec_pow2 (sum->x, sum->x, ctx); + ec_pow2 (sum->z, p2->z, ctx); + ec_mulm (prd->z, p1->z, ctx->a, ctx); /* ctx->a: (A-2)/4 */ + ec_mulm (sum->z, sum->z, dif_x, ctx); + ec_addm (prd->z, p1->x, prd->z, ctx); + ec_mulm (prd->z, prd->z, p1->z, ctx); +} + + /* RESULT = P1 + P2 */ void _gcry_mpi_ec_add_points (mpi_point_t result, @@ -1144,6 +1176,79 @@ _gcry_mpi_ec_mul_point (mpi_point_t result, } return; } + else if (ctx->model == MPI_EC_MONTGOMERY) + { + unsigned int nbits; + int j; + mpi_point_struct p1_, p2_; + unsigned long sw; + + nbits = mpi_get_nbits (scalar); + point_init (&p1); + point_init (&p2); + point_init (&p1_); + point_init (&p2_); + mpi_set_ui (p1.x, 1); + mpi_free (p2.x); + p2.x = mpi_copy (point->x); + mpi_set_ui (p2.z, 1); + + for (j=nbits-1; j >= 0; j--) + { + mpi_point_t q1, q2; + + sw = mpi_test_bit (scalar, j); + q1 = &p1; + q2 = &p2; + mpi_swap_conditional (q1->x, q2->x, sw); + mpi_swap_conditional (q1->y, q2->y, sw); + mpi_swap_conditional (q1->z, q2->z, sw); + dup_and_add_montgomery (&p1_, &p2_, q1, q2, point->x, ctx); + mpi_swap_conditional (p1_.x, p2_.x, sw); + mpi_swap_conditional (p1_.y, p2_.y, sw); + mpi_swap_conditional (p1_.z, p2_.z, sw); + + if (--j < 0) + break; + + sw = mpi_test_bit (scalar, j); + q1 = &p1_; + q2 = &p2_; + mpi_swap_conditional (q1->x, q2->x, sw); + mpi_swap_conditional (q1->y, q2->y, sw); + mpi_swap_conditional (q1->z, q2->z, sw); + dup_and_add_montgomery (&p1, &p2, q1, q2, point->x, ctx); + mpi_swap_conditional (p1.x, p2.x, sw); + mpi_swap_conditional (p1.y, p2.y, sw); + mpi_swap_conditional (p1.z, p2.z, sw); + } + + z1 = mpi_new (0); + mpi_clear (result->y); + sw = (nbits & 1); + mpi_swap_conditional (p1.x, p1_.x, sw); + mpi_swap_conditional (p1.y, p1_.y, sw); + mpi_swap_conditional (p1.z, p1_.z, sw); + + if (p1.z->nlimbs == 0) + { + mpi_set_ui (result->x, 1); + mpi_set_ui (result->z, 0); + } + else + { + ec_invm (z1, p1.z, ctx); + ec_mulm (result->x, p1.x, z1, ctx); + mpi_set_ui (result->z, 1); + } + + mpi_free (z1); + point_free (&p1); + point_free (&p2); + point_free (&p1_); + point_free (&p2_); + return; + } x1 = mpi_alloc_like (ctx->p); y1 = mpi_alloc_like (ctx->p); @@ -1266,8 +1371,12 @@ _gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx) } break; case MPI_EC_MONTGOMERY: +#if 0 log_fatal ("%s: %s not yet supported\n", "_gcry_mpi_ec_curve_point", "Montgomery"); +#else + res = 1; +#endif break; case MPI_EC_EDWARDS: { diff --git a/tests/curves.c b/tests/curves.c index 0581452..ae699d4 100644 --- a/tests/curves.c +++ b/tests/curves.c @@ -29,7 +29,7 @@ #include "../src/gcrypt-int.h" /* Number of curves defined in ../cipger/ecc.c */ -#define N_CURVES 21 +#define N_CURVES 22 /* A real world sample public key. */ static char const sample_key_1[] = @@ -64,6 +64,18 @@ static char const sample_key_2_curve[] = "brainpoolP160r1"; static unsigned int sample_key_2_nbits = 160; +/* Another sample public key. */ +static char const sample_key_3[] = +"(public-key\n" +" (ecdh\n" +" (curve Curve25519)\n" +" (q #040000000000000000000000000000000000000000000000000000000000000000" +" 0000000000000000000000000000000000000000000000000000000000000000#)\n" +" ))"; +static char const sample_key_3_curve[] = "Curve25519"; +static unsigned int sample_key_3_nbits = 256; + + /* Program option flags. */ static int verbose; static int error_count; @@ -91,6 +103,42 @@ die (const char *format, ...) } +static gcry_mpi_t +hex2mpi (const char *string) +{ + gpg_error_t err; + gcry_mpi_t val; + + err = gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL); + if (err) + die ("hex2mpi '%s' failed: %s\n", string, gpg_strerror (err)); + return val; +} + + +/* Print an MPI S-expression. */ +static void +print_mpi (const char *name, gcry_mpi_t a) +{ + gcry_error_t err; + unsigned char *buf; + int writerr = 0; + + err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buf, NULL, a); + if (err) + die ("gcry_mpi_aprint failed: %s\n", gcry_strerror (err)); + + printf (" (%s #%s#)\n", name, buf); + if (ferror (stdout)) + writerr++; + if (!writerr && fflush (stdout) == EOF) + writerr++; + if (writerr) + die ("writing output failed\n"); + gcry_free (buf); +} + + static void list_curves (void) { @@ -185,6 +233,85 @@ check_get_params (void) } +static void +check_montgomery (void) +{ + gpg_error_t err; + gcry_sexp_t key; + const char *name; + unsigned int nbits; + + gcry_ctx_t ctx; + gcry_mpi_point_t G, Q; + gcry_mpi_t d; + gcry_mpi_t x, y, z; + + err = gcry_sexp_new (&key, sample_key_3, 0, 1); + if (err) + die ("parsing s-expression string failed: %s\n", gpg_strerror (err)); + name = gcry_pk_get_curve (key, 0, &nbits); + if (!name) + fail ("curve name not found for sample_key_3\n"); + else if (strcmp (name, sample_key_3_curve)) + fail ("expected curve name %s but got %s for sample_key_3\n", + sample_key_3_curve, name); + else if (nbits != sample_key_3_nbits) + fail ("expected curve size %u but got %u for sample_key_3\n", + sample_key_3_nbits, nbits); + + gcry_sexp_release (key); + + Q = gcry_mpi_point_new (0); + + err = gcry_mpi_ec_new (&ctx, NULL, "Curve25519"); + if (err) + fail ("can't create ec context: %s\n", gpg_strerror (err)); + +#if 0 + d = hex2mpi ("40000000000000000000000000000000" + "00000000000000000000000000000000"); + G = gcry_mpi_ec_get_point ("g", ctx, 1); + if (!G) + fail ("can't get basepoint of the curve: %s\n", gpg_strerror (err)); +#else + d = hex2mpi ("7d74fb61db3100e11e4d4ae171daf820688f3bcfa631565272a998b8f4e8c290"); + { + gcry_mpi_t gx; + gx = hex2mpi ("3dc16d73d4222d12eb54623c85f3fb5ebdab33c1bd5865780654f1b0ed696ddf"); + + G = gcry_mpi_point_new (0); + gcry_mpi_point_snatch_set (G, gx, NULL, NULL); + } +#endif + + gcry_mpi_ec_mul (Q, d, G, ctx); + + x = gcry_mpi_new (0); + y = gcry_mpi_new (0); + z = gcry_mpi_new (0); + + gcry_mpi_point_get (x, y, z, Q); + + print_mpi ("Q.x", x); + print_mpi ("Q.y", y); + print_mpi ("Q.z", z); + + if (gcry_mpi_ec_get_affine (x, NULL, Q, ctx)) + fail ("failed to get affine coordinates\n"); + + print_mpi ("q.x", x); + /* 16B53A046DEEDD81ED6B0D470CE46DD9B5FAC6124F3D22358AA7CD2911FCFABC */ + + gcry_mpi_release (z); + gcry_mpi_release (y); + gcry_mpi_release (x); + + gcry_mpi_point_release (Q); + gcry_mpi_release (d); + gcry_mpi_point_release (G); + gcry_ctx_release (ctx); +} + int main (int argc, char **argv) { @@ -205,6 +332,7 @@ main (int argc, char **argv) list_curves (); check_matching (); check_get_params (); + check_montgomery (); return error_count ? 1 : 0; } diff --git a/tests/keygen.c b/tests/keygen.c index 4aff9c9..c53246c 100644 --- a/tests/keygen.c +++ b/tests/keygen.c @@ -365,7 +365,7 @@ static void check_ecc_keys (void) { const char *curves[] = { "NIST P-521", "NIST P-384", "NIST P-256", - "Ed25519", NULL }; + "Ed25519", "Curve25519", NULL }; int testno; gcry_sexp_t keyparm, key; int rc; -- From gniibe at fsij.org Thu Jun 19 07:52:59 2014 From: gniibe at fsij.org (NIIBE Yutaka) Date: Thu, 19 Jun 2014 14:52:59 +0900 Subject: [PATCH] mpi_swap_conditional Message-ID: <1403157179.2821.6.camel@cfw2.gniibe.org> Hello, For implementing Curve25519 to be constant-time, I need a function which swaps values conditionally, in constant-time. If SW=1 it swaps, it doesn't if not, both cases are executed in same timings. Here, I named it as mpi_swap_conditional. I think that this is useful for other parts of gcrypt. diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi index d59c095..91d9d8f 100644 --- a/doc/gcrypt.texi +++ b/doc/gcrypt.texi @@ -4341,6 +4341,11 @@ small values (usually up to the word size of the CPU). Swap the values of @var{a} and @var{b}. @end deftypefun + at deftypefun void gcry_mpi_swap_conditional (@w{gcry_mpi_t @var{a}}, @w{gcry_mpi_t @var{b}}, @w{unsigned long @var{sw}}) + +Swap the values of @var{a} and @var{b}, when @var{sw} is 1. + at end deftypefun + @deftypefun void gcry_mpi_snatch (@w{gcry_mpi_t @var{w}}, @ @w{const gcry_mpi_t @var{u}}) diff --git a/mpi/mpiutil.c b/mpi/mpiutil.c index fdce578..e0afec0 100644 --- a/mpi/mpiutil.c +++ b/mpi/mpiutil.c @@ -541,6 +541,43 @@ _gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b) tmp = *a; *a = *b; *b = tmp; } +void +_gcry_mpi_swap_conditional (gcry_mpi_t a, gcry_mpi_t b, unsigned long swap) +{ + size_t i; + size_t nlimbs = a->nlimbs; + unsigned long mask = -(long)swap; + + if (b->alloced < a->nlimbs) + { + mpi_resize (b, a->nlimbs); + nlimbs = a->nlimbs; + } + else if (a->alloced < b->nlimbs) + { + mpi_resize (a, b->nlimbs); + nlimbs = b->nlimbs; + } + else if (b->nlimbs < a->nlimbs) + { + mpi_resize (b, a->nlimbs); + nlimbs = b->nlimbs = a->nlimbs; + } + else if (a->nlimbs < b->nlimbs) + { + mpi_resize (a, b->nlimbs); + nlimbs = a->nlimbs = b->nlimbs; + } + + for (i = 0; i < nlimbs; i++) + { + unsigned long x = mask & (a->d[i] ^ b->d[i]); + a->d[i] = a->d[i] ^ x; + b->d[i] = b->d[i] ^ x; + } +} + + gcry_mpi_t _gcry_mpi_new (unsigned int nbits) diff --git a/src/gcrypt-int.h b/src/gcrypt-int.h index 8a6df84..42b72d6 100644 --- a/src/gcrypt-int.h +++ b/src/gcrypt-int.h @@ -371,6 +371,7 @@ gcry_mpi_t _gcry_mpi_set (gcry_mpi_t w, const gcry_mpi_t u); gcry_mpi_t _gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u); gcry_err_code_t _gcry_mpi_get_ui (gcry_mpi_t w, ulong *u); void _gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b); +void _gcry_mpi_swap_conditional (gcry_mpi_t a, gcry_mpi_t b, unsigned long sw); int _gcry_mpi_is_neg (gcry_mpi_t a); void _gcry_mpi_neg (gcry_mpi_t w, gcry_mpi_t u); void _gcry_mpi_abs (gcry_mpi_t w); @@ -475,6 +476,7 @@ int _gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); #define mpi_set_ui( w, u) _gcry_mpi_set_ui( (w), (u) ) #define mpi_get_ui(a,b) _gcry_mpi_get_ui( (a), (b) ) #define mpi_swap(a,b) _gcry_mpi_swap ((a),(b)) +#define mpi_swap_conditional(a,b,sw) _gcry_mpi_swap_conditional ((a),(b),(sw)) #define mpi_abs( w ) _gcry_mpi_abs( (w) ) #define mpi_neg( w, u) _gcry_mpi_neg( (w), (u) ) #define mpi_cmp( u, v ) _gcry_mpi_cmp( (u), (v) ) diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index bd38a24..ed0141e 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -544,6 +544,9 @@ gcry_mpi_t gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u); /* Swap the values of A and B. */ void gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b); +/* Swap the values of A and B if SW is 1. */ +void gcry_mpi_swap_conditional (gcry_mpi_t a, gcry_mpi_t b, unsigned long sw); + /* Return 1 if A is negative; 0 if zero or positive. */ int gcry_mpi_is_neg (gcry_mpi_t a); diff --git a/src/libgcrypt.def b/src/libgcrypt.def index 57ed490..aee85ac 100644 --- a/src/libgcrypt.def +++ b/src/libgcrypt.def @@ -276,5 +276,6 @@ EXPORTS gcry_mac_ctl @242 gcry_mac_get_algo @243 + gcry_mpi_swap_conditional @244 ;; end of file with public symbols for Windows. diff --git a/src/libgcrypt.vers b/src/libgcrypt.vers index 7ee0541..0540850 100644 --- a/src/libgcrypt.vers +++ b/src/libgcrypt.vers @@ -96,7 +96,7 @@ GCRYPT_1.6 { gcry_mpi_set_flag; gcry_mpi_set_highbit; gcry_mpi_set_opaque; gcry_mpi_set_opaque_copy; gcry_mpi_set_ui; gcry_mpi_snew; gcry_mpi_sub; gcry_mpi_sub_ui; - gcry_mpi_subm; gcry_mpi_swap; gcry_mpi_test_bit; + gcry_mpi_subm; gcry_mpi_swap; gcry_mpi_swap_conditional; gcry_mpi_test_bit; gcry_mpi_lshift; gcry_mpi_snatch; gcry_mpi_point_new; gcry_mpi_point_release; gcry_mpi_point_get; gcry_mpi_point_snatch_get; diff --git a/src/mpi.h b/src/mpi.h index eb0730e..7859dec 100644 --- a/src/mpi.h +++ b/src/mpi.h @@ -125,6 +125,7 @@ gcry_mpi_t _gcry_mpi_alloc_like( gcry_mpi_t a ); gcry_mpi_t _gcry_mpi_alloc_set_ui( unsigned long u); void _gcry_mpi_m_check( gcry_mpi_t a ); void _gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b); +void _gcry_mpi_swap_conditional(gcry_mpi_t a, gcry_mpi_t b, unsigned long sw); gcry_mpi_t _gcry_mpi_new (unsigned int nbits); gcry_mpi_t _gcry_mpi_snew (unsigned int nbits); gcry_mpi_t _gcry_mpi_set_opaque_copy (gcry_mpi_t a, diff --git a/src/visibility.c b/src/visibility.c index 6ed57ca..ec3b644 100644 --- a/src/visibility.c +++ b/src/visibility.c @@ -319,6 +319,12 @@ gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b) _gcry_mpi_swap (a, b); } +void +gcry_mpi_swap_conditional (gcry_mpi_t a, gcry_mpi_t b, unsigned long sw) +{ + _gcry_mpi_swap_conditional (a, b, sw); +} + int gcry_mpi_is_neg (gcry_mpi_t a) { diff --git a/src/visibility.h b/src/visibility.h index 96b5235..54767e3 100644 --- a/src/visibility.h +++ b/src/visibility.h @@ -266,6 +266,7 @@ MARK_VISIBLEX (gcry_mpi_sub) MARK_VISIBLEX (gcry_mpi_sub_ui) MARK_VISIBLEX (gcry_mpi_subm) MARK_VISIBLEX (gcry_mpi_swap) +MARK_VISIBLEX (gcry_mpi_swap_conditional) MARK_VISIBLEX (gcry_mpi_test_bit) MARK_VISIBLEX (gcry_ctx_release) @@ -482,6 +483,7 @@ MARK_VISIBLEX (_gcry_mpi_get_const) #define gcry_mpi_sub_ui _gcry_USE_THE_UNDERSCORED_FUNCTION #define gcry_mpi_subm _gcry_USE_THE_UNDERSCORED_FUNCTION #define gcry_mpi_swap _gcry_USE_THE_UNDERSCORED_FUNCTION +#define gcry_mpi_swap_conditional _gcry_USE_THE_UNDERSCORED_FUNCTION #define gcry_mpi_test_bit _gcry_USE_THE_UNDERSCORED_FUNCTION #define gcry_mpi_abs _gcry_USE_THE_UNDERSCORED_FUNCTION -- From dbaryshkov at gmail.com Thu Jun 19 11:03:29 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Thu, 19 Jun 2014 13:03:29 +0400 Subject: [PATCH] mpi_swap_conditional In-Reply-To: <1403157179.2821.6.camel@cfw2.gniibe.org> References: <1403157179.2821.6.camel@cfw2.gniibe.org> Message-ID: Hello, On Thu, Jun 19, 2014 at 9:52 AM, NIIBE Yutaka wrote: [skipped] > diff --git a/mpi/mpiutil.c b/mpi/mpiutil.c > index fdce578..e0afec0 100644 > --- a/mpi/mpiutil.c > +++ b/mpi/mpiutil.c > @@ -541,6 +541,43 @@ _gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b) > tmp = *a; *a = *b; *b = tmp; > } > > +void > +_gcry_mpi_swap_conditional (gcry_mpi_t a, gcry_mpi_t b, unsigned long swap) > +{ > + size_t i; > + size_t nlimbs = a->nlimbs; > + unsigned long mask = -(long)swap; I'd suggest to have something like unsigned long mask = 0Ul - !!swap; That would be more robust - you can use then all expressions as 'swap' argument instead of plain 0 or 1. -- With best wishes Dmitry From gniibe at fsij.org Thu Jun 19 11:04:13 2014 From: gniibe at fsij.org (NIIBE Yutaka) Date: Thu, 19 Jun 2014 18:04:13 +0900 Subject: [PATCH] Curve25519 patch revised In-Reply-To: <1403157515.2821.8.camel@cfw2.gniibe.org> References: <1403157515.2821.8.camel@cfw2.gniibe.org> Message-ID: <1403168653.2821.9.camel@cfw2.gniibe.org> On 2014-06-19 at 14:58 +0900, NIIBE Yutaka wrote: > Here is a revised patch for Curve25519 support. With > mpi_swap_conditional, it's getting to constant-time. Sorry, both patches are not good, it causes failure. It's just to show what I'm working. Please don't use it. Next time, I will post after confirming that it will pass all tests of "make check". -- From gniibe at fsij.org Thu Jun 19 11:10:14 2014 From: gniibe at fsij.org (NIIBE Yutaka) Date: Thu, 19 Jun 2014 18:10:14 +0900 Subject: [PATCH] mpi_swap_conditional In-Reply-To: References: <1403157179.2821.6.camel@cfw2.gniibe.org> Message-ID: <1403169014.2821.10.camel@cfw2.gniibe.org> On 2014-06-19 at 13:03 +0400, Dmitry Eremin-Solenikov wrote: > I'd suggest to have something like > unsigned long mask = 0Ul - !!swap; > That would be more robust - you can use then all > expressions as 'swap' argument instead of plain 0 or 1. Thank you for your suggestion. I will do that in the next revised patch. Note that it doesn't work well yet. -- From ian at cypherpunks.ca Thu Jun 19 20:08:32 2014 From: ian at cypherpunks.ca (Ian Goldberg) Date: Thu, 19 Jun 2014 14:08:32 -0400 Subject: [PATCH] mpi_swap_conditional In-Reply-To: <1403157179.2821.6.camel@cfw2.gniibe.org> References: <1403157179.2821.6.camel@cfw2.gniibe.org> Message-ID: <20140619180832.GT15064@thunk.cs.uwaterloo.ca> On Thu, Jun 19, 2014 at 02:52:59PM +0900, NIIBE Yutaka wrote: > Hello, > > For implementing Curve25519 to be constant-time, I need a function > which swaps values conditionally, in constant-time. If SW=1 it swaps, > it doesn't if not, both cases are executed in same timings. So the values of a and b are public, but only the value of SW is private? Isn't that a pretty unusual case? The timing of the code below definitely depends on the values (in particular the relative sizes) of a and b, so if a and b are non-public, this is not a constant-time routine, right? > + if (b->alloced < a->nlimbs) > + { > + mpi_resize (b, a->nlimbs); > + nlimbs = a->nlimbs; > + } > + else if (a->alloced < b->nlimbs) > + { > + mpi_resize (a, b->nlimbs); > + nlimbs = b->nlimbs; > + } > + else if (b->nlimbs < a->nlimbs) > + { > + mpi_resize (b, a->nlimbs); > + nlimbs = b->nlimbs = a->nlimbs; > + } > + else if (a->nlimbs < b->nlimbs) > + { > + mpi_resize (a, b->nlimbs); > + nlimbs = a->nlimbs = b->nlimbs; > + } - Ian From gniibe at fsij.org Fri Jun 20 03:58:26 2014 From: gniibe at fsij.org (NIIBE Yutaka) Date: Fri, 20 Jun 2014 10:58:26 +0900 Subject: [PATCH] mpi_swap_conditional In-Reply-To: <20140619180832.GT15064@thunk.cs.uwaterloo.ca> References: <1403157179.2821.6.camel@cfw2.gniibe.org> <20140619180832.GT15064@thunk.cs.uwaterloo.ca> Message-ID: <1403229506.2376.1.camel@cfw2.gniibe.org> On 2014-06-19 at 14:08 -0400, Ian Goldberg wrote: > So the values of a and b are public, but only the value of SW is > private? Isn't that a pretty unusual case? The timing of the code > below definitely depends on the values (in particular the relative > sizes) of a and b, so if a and b are non-public, this is not a > constant-time routine, right? I'm sorry that my code was too bad and caused confusion. Here is today's version. ============================================== void _gcry_mpi_swap_conditional (gcry_mpi_t a, gcry_mpi_t b, unsigned long swap) { size_t i; size_t nlimbs = a->alloced; unsigned long mask = 0UL - !!swap; unsigned long x; if (a->alloced != b->alloced) log_bug ("mpi_swap_conditional: different sizes\n"); for (i = 0; i < nlimbs; i++) { x = mask & (a->d[i] ^ b->d[i]); a->d[i] = a->d[i] ^ x; b->d[i] = b->d[i] ^ x; } x = mask & (a->nlimbs ^ b->nlimbs); a->nlimbs = a->nlimbs ^ x; b->nlimbs = b->nlimbs ^ x; x = mask & (a->sign ^ b->sign); a->sign = a->sign ^ x; b->sign = b->sign ^ x; } ============================================== Now, it is caller's responsibility to keep same sizes of A and B. The calculation is as same as: if (swap) _gcry_mpi_swap (a, b); But _gcry_mpi_swap_conditional does swapping at lower level, to enable same cache usage pattern of caller and the intention of the implementation is constant-time (not to depend SWAP). The intended usage is allocating MPI at the beginning, and use mpi_swap_conditional in the loop of crypto computation, where SWAP is private. Since I think that there is no guarantee that we can keep using same place of MPI memory, it would be possible log_bug will be called, I'm afraid. Please see my next post for actual usage. -- From gniibe at fsij.org Fri Jun 20 04:23:55 2014 From: gniibe at fsij.org (NIIBE Yutaka) Date: Fri, 20 Jun 2014 11:23:55 +0900 Subject: [PATCH] Curve25519 patch revised In-Reply-To: <1403168653.2821.9.camel@cfw2.gniibe.org> References: <1403157515.2821.8.camel@cfw2.gniibe.org> <1403168653.2821.9.camel@cfw2.gniibe.org> Message-ID: <1403231035.2376.2.camel@cfw2.gniibe.org> On 2014-06-19 at 18:04 +0900, NIIBE Yutaka wrote: > Next time, I will post after confirming that it will pass all tests of > "make check". Here is revised patch which include mpi_swap_conditional. mpi_swap_conditional is used in _gcry_mpi_ec_mul_point for Montgomery curve (model == MPI_EC_MONTGOMERY). It success for "make check". It's not yet complete, I have not decided where we should put the code of: mpi_clear_bit (scalar, 255); mpi_set_bit (scalar, 254); mpi_clear_bit (scalar, 2); mpi_clear_bit (scalar, 1); mpi_clear_bit (scalar, 0); To do so, we need to add two more fields in the curve specification: co-factor and number of bits of the curve (to set MSB of above code). diff --git a/cipher/ecc-curves.c b/cipher/ecc-curves.c index 0f622f7..e7dbc17 100644 --- a/cipher/ecc-curves.c +++ b/cipher/ecc-curves.c @@ -40,7 +40,7 @@ static const struct const char *other; /* Other name. */ } curve_aliases[] = { - /*{ "Curve25519", "1.3.6.1.4.1.3029.1.5.1" },*/ + { "Curve25519", "1.3.6.1.4.1.3029.1.5.1" }, { "Ed25519", "1.3.6.1.4.1.11591.15.1" }, { "NIST P-192", "1.2.840.10045.3.1.1" }, /* X9.62 OID */ @@ -127,6 +127,17 @@ static const ecc_domain_parms_t domain_parms[] = "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A", "0x6666666666666666666666666666666666666666666666666666666666666658" }, + { + /* (y^2 = x^3 + 486662*x^2 + x) */ + "Curve25519", 256, 0, + MPI_EC_MONTGOMERY, ECC_DIALECT_STANDARD, + "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED", + "0x01DB41", + "0x01", + "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", + "0x0000000000000000000000000000000000000000000000000000000000000009", + "0x20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9" + }, #if 0 /* No real specs yet found. */ { /* x^2 + y^2 = 1 + 3617x^2y^2 mod 2^414 - 17 */ @@ -507,9 +518,8 @@ _gcry_ecc_fill_in_curve (unsigned int nbits, const char *name, { case MPI_EC_WEIERSTRASS: case MPI_EC_EDWARDS: - break; case MPI_EC_MONTGOMERY: - return GPG_ERR_NOT_SUPPORTED; + break; default: return GPG_ERR_BUG; } diff --git a/cipher/ecc.c b/cipher/ecc.c index e0be2d4..09de65f 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -117,7 +117,24 @@ nist_generate_key (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx, point_init (&Q); /* Generate a secret. */ - if (ctx->dialect == ECC_DIALECT_ED25519) + /* + * FIXME. It should be something like this: + * + * When the co-factor of the curve is not 1, we guarantee that + * scalar value k is multiple of its co-factor to avoid sub-group + * attack. Also, we make sure that the most significant bit of k + * is 1. + * + * It works for now as we only have two curves which have co-factor!=1; + * Ed25519 and Curve25519. + * Note that we need some a way to get number of bits of the curve to + * set MSB of k. Currently, E.nbits is not precise for this purpuse. + * We also need a way to get co-factor of a curve. + * + * Currently, we distinguish the two curves by ECC_DIALECT_ED25519 + * and MPI_EC_MONTGOMERY, which works, but is not that correct. + */ + if (ctx->dialect == ECC_DIALECT_ED25519 || E->model == MPI_EC_MONTGOMERY) { char *rndbuf; @@ -156,7 +174,7 @@ nist_generate_key (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx, * possibilities without any loss of security. Note that we don't * do that for Ed25519 so that we do not violate the special * construction of the secret key. */ - if (E->dialect == ECC_DIALECT_ED25519) + if (E->dialect == ECC_DIALECT_ED25519 || E->model == MPI_EC_MONTGOMERY) point_set (&sk->Q, &Q); else { @@ -227,12 +245,8 @@ static void test_keys (ECC_secret_key *sk, unsigned int nbits) { ECC_public_key pk; - gcry_mpi_t test = mpi_new (nbits); + gcry_mpi_t test; mpi_point_struct R_; - gcry_mpi_t c = mpi_new (nbits); - gcry_mpi_t out = mpi_new (nbits); - gcry_mpi_t r = mpi_new (nbits); - gcry_mpi_t s = mpi_new (nbits); if (DBG_CIPHER) log_debug ("Testing key.\n"); @@ -243,27 +257,82 @@ test_keys (ECC_secret_key *sk, unsigned int nbits) point_init (&pk.Q); point_set (&pk.Q, &sk->Q); - _gcry_mpi_randomize (test, nbits, GCRY_WEAK_RANDOM); + if (sk->E.model == MPI_EC_MONTGOMERY) + /* It's ECDH only. */ + /* FIXME: see the FIXME comment of nist_generate_key. + * Here, we generate ephemeral key, same handling is needed for secret. + */ + { + char *rndbuf; + gcry_mpi_t x0, x1; + mpi_ec_t ec; + + test = mpi_new (256); + rndbuf = _gcry_random_bytes (32, GCRY_WEAK_RANDOM); + rndbuf[0] &= 0x7f; /* Clear bit 255. */ + rndbuf[0] |= 0x40; /* Set bit 254. */ + rndbuf[31] &= 0xf8; /* Clear bits 2..0 so that d mod 8 == 0 */ + _gcry_mpi_set_buffer (test, rndbuf, 32, 0); + xfree (rndbuf); + + ec = _gcry_mpi_ec_p_internal_new (pk.E.model, pk.E.dialect, 0, + pk.E.p, pk.E.a, pk.E.b); + x0 = mpi_new (0); + x1 = mpi_new (0); - if (_gcry_ecc_ecdsa_sign (test, sk, r, s, 0, 0) ) - log_fatal ("ECDSA operation: sign failed\n"); + /* R_ = kQ <=> R_ = kdG */ + _gcry_mpi_ec_mul_point (&R_, test, &pk.Q, ec); + if (_gcry_mpi_ec_get_affine (x0, NULL, &R_, ec)) + log_fatal ("ecdh: Failed to get affine coordinates for kQ\n"); - if (_gcry_ecc_ecdsa_verify (test, &pk, r, s)) - { - log_fatal ("ECDSA operation: sign, verify failed\n"); + /* R_ = kG */ + _gcry_mpi_ec_mul_point (&R_, test, &pk.E.G, ec); + /* R_ = dkG */ + _gcry_mpi_ec_mul_point (&R_, sk->d, &R_, ec); + + if (_gcry_mpi_ec_get_affine (x1, NULL, &R_, ec)) + log_fatal ("ecdh: Failed to get affine coordinates for dkG\n"); + + if (mpi_cmp (x0, x1)) + { + log_fatal ("ECDH test failed.\n"); + } + + mpi_free (x0); + mpi_free (x1); + _gcry_mpi_ec_free (ec); } + else + { + gcry_mpi_t c = mpi_new (nbits); + gcry_mpi_t out = mpi_new (nbits); + gcry_mpi_t r = mpi_new (nbits); + gcry_mpi_t s = mpi_new (nbits); - if (DBG_CIPHER) - log_debug ("ECDSA operation: sign, verify ok.\n"); + test = mpi_new (nbits); + _gcry_mpi_randomize (test, nbits, GCRY_WEAK_RANDOM); + + if (_gcry_ecc_ecdsa_sign (test, sk, r, s, 0, 0) ) + log_fatal ("ECDSA operation: sign failed\n"); + + if (_gcry_ecc_ecdsa_verify (test, &pk, r, s)) + { + log_fatal ("ECDSA operation: sign, verify failed\n"); + } + + if (DBG_CIPHER) + log_debug ("ECDSA operation: sign, verify ok.\n"); + + mpi_free (s); + mpi_free (r); + mpi_free (out); + mpi_free (c); + } point_free (&pk.Q); _gcry_ecc_curve_free (&pk.E); point_free (&R_); - mpi_free (s); - mpi_free (r); - mpi_free (out); - mpi_free (c); mpi_free (test); } @@ -302,7 +371,7 @@ check_secret_key (ECC_secret_key *sk, mpi_ec_t ec, int flags) } /* Check order of curve. */ - if (sk->E.dialect != ECC_DIALECT_ED25519) + if (sk->E.dialect != ECC_DIALECT_ED25519 && sk->E.model != MPI_EC_MONTGOMERY) { _gcry_mpi_ec_mul_point (&Q, sk->E.n, &sk->E.G, ec); if (mpi_cmp_ui (Q.z, 0)) diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi index d59c095..91d9d8f 100644 --- a/doc/gcrypt.texi +++ b/doc/gcrypt.texi @@ -4341,6 +4341,11 @@ small values (usually up to the word size of the CPU). Swap the values of @var{a} and @var{b}. @end deftypefun + at deftypefun void gcry_mpi_swap_conditional (@w{gcry_mpi_t @var{a}}, @w{gcry_mpi_t @var{b}}, @w{unsigned long @var{sw}}) + +Swap the values of @var{a} and @var{b}, when @var{sw} is 1. + at end deftypefun + @deftypefun void gcry_mpi_snatch (@w{gcry_mpi_t @var{w}}, @ @w{const gcry_mpi_t @var{u}}) diff --git a/mpi/ec.c b/mpi/ec.c index 4f35de0..c9997b5 100644 --- a/mpi/ec.c +++ b/mpi/ec.c @@ -600,10 +600,13 @@ _gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t point, case MPI_EC_MONTGOMERY: { - log_fatal ("%s: %s not yet supported\n", - "_gcry_mpi_ec_get_affine", "Montgomery"); + if (x) + mpi_set (x, point->x); + + if (y) + mpi_set (y, point->y); } - return -1; + return 0; case MPI_EC_EDWARDS: { @@ -1073,6 +1076,35 @@ add_points_edwards (mpi_point_t result, } +/* PRD = 2 * P1. + SUM = P1 + P2. + P1 - P2 = DIF */ +static void +dup_and_add_montgomery (mpi_point_t prd, mpi_point_t sum, + mpi_point_t p1, mpi_point_t p2, gcry_mpi_t dif_x, + mpi_ec_t ctx) +{ + ec_addm (sum->x, p2->x, p2->z, ctx); + ec_subm (p2->z, p2->x, p2->z, ctx); + ec_addm (prd->x, p1->x, p1->z, ctx); + ec_subm (p1->z, p1->x, p1->z, ctx); + ec_mulm (p2->x, p1->z, sum->x, ctx); + ec_mulm (p2->z, prd->x, p2->z, ctx); + ec_pow2 (p1->x, prd->x, ctx); + ec_pow2 (p1->z, p1->z, ctx); + ec_addm (sum->x, p2->x, p2->z, ctx); + ec_subm (p2->z, p2->x, p2->z, ctx); + ec_mulm (prd->x, p1->x, p1->z, ctx); + ec_subm (p1->z, p1->x, p1->z, ctx); + ec_pow2 (sum->x, sum->x, ctx); + ec_pow2 (sum->z, p2->z, ctx); + ec_mulm (prd->z, p1->z, ctx->a, ctx); /* ctx->a: (A-2)/4 */ + ec_mulm (sum->z, sum->z, dif_x, ctx); + ec_addm (prd->z, p1->x, prd->z, ctx); + ec_mulm (prd->z, prd->z, p1->z, ctx); +} + + /* RESULT = P1 + P2 */ void _gcry_mpi_ec_add_points (mpi_point_t result, @@ -1144,6 +1176,86 @@ _gcry_mpi_ec_mul_point (mpi_point_t result, } return; } + else if (ctx->model == MPI_EC_MONTGOMERY) + { + unsigned int nbits; + int j; + mpi_point_struct p1_, p2_; + mpi_point_t q1, q2, prd, sum; + unsigned long sw; + size_t nlimbs; + + /* FIXME: it's just for Curve25519 */ + mpi_clear_bit (scalar, 255); + mpi_set_bit (scalar, 254); + mpi_clear_bit (scalar, 2); + mpi_clear_bit (scalar, 1); + mpi_clear_bit (scalar, 0); + + nbits = mpi_get_nbits (scalar); + point_init (&p1); + point_init (&p2); + point_init (&p1_); + point_init (&p2_); + mpi_set_ui (p1.x, 1); + mpi_free (p2.x); + p2.x = mpi_copy (point->x); + mpi_set_ui (p2.z, 1); + + nlimbs = 2*(nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB+1; + mpi_resize (p1.x, nlimbs); + mpi_resize (p1.z, nlimbs); + mpi_resize (p2.x, nlimbs); + mpi_resize (p2.z, nlimbs); + mpi_resize (p1_.x, nlimbs); + mpi_resize (p1_.z, nlimbs); + mpi_resize (p2_.x, nlimbs); + mpi_resize (p2_.z, nlimbs); + + q1 = &p1; + q2 = &p2; + prd = &p1_; + sum = &p2_; + for (j=nbits-1; j >= 0; j--) + { + mpi_point_t t; + + sw = mpi_test_bit (scalar, j); + mpi_swap_conditional (q1->x, q2->x, sw); + mpi_swap_conditional (q1->z, q2->z, sw); + dup_and_add_montgomery (prd, sum, q1, q2, point->x, ctx); + mpi_swap_conditional (prd->x, sum->x, sw); + mpi_swap_conditional (prd->z, sum->z, sw); + + t = q1; q1 = prd; prd = t; + t = q2; q2 = sum; sum = t; + } + + mpi_clear (result->y); + sw = (nbits & 1); + mpi_swap_conditional (p1.x, p1_.x, sw); + mpi_swap_conditional (p1.z, p1_.z, sw); + + if (p1.z->nlimbs == 0) + { + mpi_set_ui (result->x, 1); + mpi_set_ui (result->z, 0); + } + else + { + z1 = mpi_new (0); + ec_invm (z1, p1.z, ctx); + ec_mulm (result->x, p1.x, z1, ctx); + mpi_set_ui (result->z, 1); + mpi_free (z1); + } + + point_free (&p1); + point_free (&p2); + point_free (&p1_); + point_free (&p2_); + return; + } x1 = mpi_alloc_like (ctx->p); y1 = mpi_alloc_like (ctx->p); @@ -1266,8 +1378,12 @@ _gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx) } break; case MPI_EC_MONTGOMERY: +#if 0 log_fatal ("%s: %s not yet supported\n", "_gcry_mpi_ec_curve_point", "Montgomery"); +#else + res = 1; +#endif break; case MPI_EC_EDWARDS: { diff --git a/mpi/mpiutil.c b/mpi/mpiutil.c index fdce578..5e77e12 100644 --- a/mpi/mpiutil.c +++ b/mpi/mpiutil.c @@ -541,6 +541,34 @@ _gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b) tmp = *a; *a = *b; *b = tmp; } +void +_gcry_mpi_swap_conditional (gcry_mpi_t a, gcry_mpi_t b, unsigned long swap) +{ + size_t i; + size_t nlimbs = a->alloced; + unsigned long mask = 0UL - !!swap; + unsigned long x; + + if (a->alloced != b->alloced) + log_bug ("mpi_swap_conditional: different sizes\n"); + + for (i = 0; i < nlimbs; i++) + { + x = mask & (a->d[i] ^ b->d[i]); + a->d[i] = a->d[i] ^ x; + b->d[i] = b->d[i] ^ x; + } + + x = mask & (a->nlimbs ^ b->nlimbs); + a->nlimbs = a->nlimbs ^ x; + b->nlimbs = b->nlimbs ^ x; + + x = mask & (a->sign ^ b->sign); + a->sign = a->sign ^ x; + b->sign = b->sign ^ x; +} + + gcry_mpi_t _gcry_mpi_new (unsigned int nbits) diff --git a/src/gcrypt-int.h b/src/gcrypt-int.h index 8a6df84..42b72d6 100644 --- a/src/gcrypt-int.h +++ b/src/gcrypt-int.h @@ -371,6 +371,7 @@ gcry_mpi_t _gcry_mpi_set (gcry_mpi_t w, const gcry_mpi_t u); gcry_mpi_t _gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u); gcry_err_code_t _gcry_mpi_get_ui (gcry_mpi_t w, ulong *u); void _gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b); +void _gcry_mpi_swap_conditional (gcry_mpi_t a, gcry_mpi_t b, unsigned long sw); int _gcry_mpi_is_neg (gcry_mpi_t a); void _gcry_mpi_neg (gcry_mpi_t w, gcry_mpi_t u); void _gcry_mpi_abs (gcry_mpi_t w); @@ -475,6 +476,7 @@ int _gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); #define mpi_set_ui( w, u) _gcry_mpi_set_ui( (w), (u) ) #define mpi_get_ui(a,b) _gcry_mpi_get_ui( (a), (b) ) #define mpi_swap(a,b) _gcry_mpi_swap ((a),(b)) +#define mpi_swap_conditional(a,b,sw) _gcry_mpi_swap_conditional ((a),(b),(sw)) #define mpi_abs( w ) _gcry_mpi_abs( (w) ) #define mpi_neg( w, u) _gcry_mpi_neg( (w), (u) ) #define mpi_cmp( u, v ) _gcry_mpi_cmp( (u), (v) ) diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index bd38a24..ed0141e 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -544,6 +544,9 @@ gcry_mpi_t gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u); /* Swap the values of A and B. */ void gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b); +/* Swap the values of A and B if SW is 1. */ +void gcry_mpi_swap_conditional (gcry_mpi_t a, gcry_mpi_t b, unsigned long sw); + /* Return 1 if A is negative; 0 if zero or positive. */ int gcry_mpi_is_neg (gcry_mpi_t a); diff --git a/src/libgcrypt.def b/src/libgcrypt.def index 57ed490..aee85ac 100644 --- a/src/libgcrypt.def +++ b/src/libgcrypt.def @@ -276,5 +276,6 @@ EXPORTS gcry_mac_ctl @242 gcry_mac_get_algo @243 + gcry_mpi_swap_conditional @244 ;; end of file with public symbols for Windows. diff --git a/src/libgcrypt.vers b/src/libgcrypt.vers index 7ee0541..0540850 100644 --- a/src/libgcrypt.vers +++ b/src/libgcrypt.vers @@ -96,7 +96,7 @@ GCRYPT_1.6 { gcry_mpi_set_flag; gcry_mpi_set_highbit; gcry_mpi_set_opaque; gcry_mpi_set_opaque_copy; gcry_mpi_set_ui; gcry_mpi_snew; gcry_mpi_sub; gcry_mpi_sub_ui; - gcry_mpi_subm; gcry_mpi_swap; gcry_mpi_test_bit; + gcry_mpi_subm; gcry_mpi_swap; gcry_mpi_swap_conditional; gcry_mpi_test_bit; gcry_mpi_lshift; gcry_mpi_snatch; gcry_mpi_point_new; gcry_mpi_point_release; gcry_mpi_point_get; gcry_mpi_point_snatch_get; diff --git a/src/mpi.h b/src/mpi.h index eb0730e..7859dec 100644 --- a/src/mpi.h +++ b/src/mpi.h @@ -125,6 +125,7 @@ gcry_mpi_t _gcry_mpi_alloc_like( gcry_mpi_t a ); gcry_mpi_t _gcry_mpi_alloc_set_ui( unsigned long u); void _gcry_mpi_m_check( gcry_mpi_t a ); void _gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b); +void _gcry_mpi_swap_conditional(gcry_mpi_t a, gcry_mpi_t b, unsigned long sw); gcry_mpi_t _gcry_mpi_new (unsigned int nbits); gcry_mpi_t _gcry_mpi_snew (unsigned int nbits); gcry_mpi_t _gcry_mpi_set_opaque_copy (gcry_mpi_t a, diff --git a/src/visibility.c b/src/visibility.c index 6ed57ca..ec3b644 100644 --- a/src/visibility.c +++ b/src/visibility.c @@ -319,6 +319,12 @@ gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b) _gcry_mpi_swap (a, b); } +void +gcry_mpi_swap_conditional (gcry_mpi_t a, gcry_mpi_t b, unsigned long sw) +{ + _gcry_mpi_swap_conditional (a, b, sw); +} + int gcry_mpi_is_neg (gcry_mpi_t a) { diff --git a/src/visibility.h b/src/visibility.h index 96b5235..54767e3 100644 --- a/src/visibility.h +++ b/src/visibility.h @@ -266,6 +266,7 @@ MARK_VISIBLEX (gcry_mpi_sub) MARK_VISIBLEX (gcry_mpi_sub_ui) MARK_VISIBLEX (gcry_mpi_subm) MARK_VISIBLEX (gcry_mpi_swap) +MARK_VISIBLEX (gcry_mpi_swap_conditional) MARK_VISIBLEX (gcry_mpi_test_bit) MARK_VISIBLEX (gcry_ctx_release) @@ -482,6 +483,7 @@ MARK_VISIBLEX (_gcry_mpi_get_const) #define gcry_mpi_sub_ui _gcry_USE_THE_UNDERSCORED_FUNCTION #define gcry_mpi_subm _gcry_USE_THE_UNDERSCORED_FUNCTION #define gcry_mpi_swap _gcry_USE_THE_UNDERSCORED_FUNCTION +#define gcry_mpi_swap_conditional _gcry_USE_THE_UNDERSCORED_FUNCTION #define gcry_mpi_test_bit _gcry_USE_THE_UNDERSCORED_FUNCTION #define gcry_mpi_abs _gcry_USE_THE_UNDERSCORED_FUNCTION diff --git a/tests/curves.c b/tests/curves.c index 0581452..ae699d4 100644 --- a/tests/curves.c +++ b/tests/curves.c @@ -29,7 +29,7 @@ #include "../src/gcrypt-int.h" /* Number of curves defined in ../cipger/ecc.c */ -#define N_CURVES 21 +#define N_CURVES 22 /* A real world sample public key. */ static char const sample_key_1[] = @@ -64,6 +64,18 @@ static char const sample_key_2_curve[] = "brainpoolP160r1"; static unsigned int sample_key_2_nbits = 160; +/* Another sample public key. */ +static char const sample_key_3[] = +"(public-key\n" +" (ecdh\n" +" (curve Curve25519)\n" +" (q #040000000000000000000000000000000000000000000000000000000000000000" +" 0000000000000000000000000000000000000000000000000000000000000000#)\n" +" ))"; +static char const sample_key_3_curve[] = "Curve25519"; +static unsigned int sample_key_3_nbits = 256; + + /* Program option flags. */ static int verbose; static int error_count; @@ -91,6 +103,42 @@ die (const char *format, ...) } +static gcry_mpi_t +hex2mpi (const char *string) +{ + gpg_error_t err; + gcry_mpi_t val; + + err = gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL); + if (err) + die ("hex2mpi '%s' failed: %s\n", string, gpg_strerror (err)); + return val; +} + + +/* Print an MPI S-expression. */ +static void +print_mpi (const char *name, gcry_mpi_t a) +{ + gcry_error_t err; + unsigned char *buf; + int writerr = 0; + + err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buf, NULL, a); + if (err) + die ("gcry_mpi_aprint failed: %s\n", gcry_strerror (err)); + + printf (" (%s #%s#)\n", name, buf); + if (ferror (stdout)) + writerr++; + if (!writerr && fflush (stdout) == EOF) + writerr++; + if (writerr) + die ("writing output failed\n"); + gcry_free (buf); +} + + static void list_curves (void) { @@ -185,6 +233,85 @@ check_get_params (void) } +static void +check_montgomery (void) +{ + gpg_error_t err; + gcry_sexp_t key; + const char *name; + unsigned int nbits; + + gcry_ctx_t ctx; + gcry_mpi_point_t G, Q; + gcry_mpi_t d; + gcry_mpi_t x, y, z; + + err = gcry_sexp_new (&key, sample_key_3, 0, 1); + if (err) + die ("parsing s-expression string failed: %s\n", gpg_strerror (err)); + name = gcry_pk_get_curve (key, 0, &nbits); + if (!name) + fail ("curve name not found for sample_key_3\n"); + else if (strcmp (name, sample_key_3_curve)) + fail ("expected curve name %s but got %s for sample_key_3\n", + sample_key_3_curve, name); + else if (nbits != sample_key_3_nbits) + fail ("expected curve size %u but got %u for sample_key_3\n", + sample_key_3_nbits, nbits); + + gcry_sexp_release (key); + + Q = gcry_mpi_point_new (0); + + err = gcry_mpi_ec_new (&ctx, NULL, "Curve25519"); + if (err) + fail ("can't create ec context: %s\n", gpg_strerror (err)); + +#if 0 + d = hex2mpi ("40000000000000000000000000000000" + "00000000000000000000000000000000"); + G = gcry_mpi_ec_get_point ("g", ctx, 1); + if (!G) + fail ("can't get basepoint of the curve: %s\n", gpg_strerror (err)); +#else + d = hex2mpi ("7d74fb61db3100e11e4d4ae171daf820688f3bcfa631565272a998b8f4e8c290"); + { + gcry_mpi_t gx; + gx = hex2mpi ("3dc16d73d4222d12eb54623c85f3fb5ebdab33c1bd5865780654f1b0ed696ddf"); + + G = gcry_mpi_point_new (0); + gcry_mpi_point_snatch_set (G, gx, NULL, NULL); + } +#endif + + gcry_mpi_ec_mul (Q, d, G, ctx); + + x = gcry_mpi_new (0); + y = gcry_mpi_new (0); + z = gcry_mpi_new (0); + + gcry_mpi_point_get (x, y, z, Q); + + print_mpi ("Q.x", x); + print_mpi ("Q.y", y); + print_mpi ("Q.z", z); + + if (gcry_mpi_ec_get_affine (x, NULL, Q, ctx)) + fail ("failed to get affine coordinates\n"); + + print_mpi ("q.x", x); + /* 16B53A046DEEDD81ED6B0D470CE46DD9B5FAC6124F3D22358AA7CD2911FCFABC */ + + gcry_mpi_release (z); + gcry_mpi_release (y); + gcry_mpi_release (x); + + gcry_mpi_point_release (Q); + gcry_mpi_release (d); + gcry_mpi_point_release (G); + gcry_ctx_release (ctx); +} + int main (int argc, char **argv) { @@ -205,6 +332,7 @@ main (int argc, char **argv) list_curves (); check_matching (); check_get_params (); + check_montgomery (); return error_count ? 1 : 0; } diff --git a/tests/keygen.c b/tests/keygen.c index 4aff9c9..c53246c 100644 --- a/tests/keygen.c +++ b/tests/keygen.c @@ -365,7 +365,7 @@ static void check_ecc_keys (void) { const char *curves[] = { "NIST P-521", "NIST P-384", "NIST P-256", - "Ed25519", NULL }; + "Ed25519", "Curve25519", NULL }; int testno; gcry_sexp_t keyparm, key; int rc; -- From wk at gnupg.org Fri Jun 20 11:08:16 2014 From: wk at gnupg.org (Werner Koch) Date: Fri, 20 Jun 2014 11:08:16 +0200 Subject: [PATCH] Curve25519 patch revised In-Reply-To: <1403231035.2376.2.camel@cfw2.gniibe.org> (NIIBE Yutaka's message of "Fri, 20 Jun 2014 11:23:55 +0900") References: <1403157515.2821.8.camel@cfw2.gniibe.org> <1403168653.2821.9.camel@cfw2.gniibe.org> <1403231035.2376.2.camel@cfw2.gniibe.org> Message-ID: <87a998ne2n.fsf@vigenere.g10code.de> On Fri, 20 Jun 2014 04:23, gniibe at fsij.org said: > mpi_swap_conditional is used in _gcry_mpi_ec_mul_point for Montgomery > curve (model == MPI_EC_MONTGOMERY). Can you change the name to mpi_swap_cond ? I would also prefer to keep it an internal function for now and add it to the public API only later. This allows to backport it to 1.6. > To do so, we need to add two more fields in the curve specification: > co-factor and number of bits of the curve (to set MSB of above code). No problem. Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From sreeharsha at totakura.in Fri Jun 20 12:14:24 2014 From: sreeharsha at totakura.in (Sree Harsha Totakura) Date: Fri, 20 Jun 2014 12:14:24 +0200 Subject: Comparing EC MPI points In-Reply-To: <53917C25.4020203@totakura.in> References: <539172A3.103@totakura.in> <53917C25.4020203@totakura.in> Message-ID: <53A40980.3030307@totakura.in> On 06/06/2014 10:30 AM, Sree Harsha Totakura wrote: > I found a way: compare the points' coordinates after retrieving them with > gcry_mpi_point_get() Just FYI for the ones arriving here via Internet searches. You should use gcry_mpi_point_get_affine() instead of gcry_mpi_point_get() since the projective coordinates given by the latter function can be expressed differently for a given point. The affine coordinates do not have this problem. Sree From gniibe at fsij.org Fri Jun 20 15:28:59 2014 From: gniibe at fsij.org (NIIBE Yutaka) Date: Fri, 20 Jun 2014 22:28:59 +0900 Subject: [PATCH] Curve25519 patch revised In-Reply-To: <87a998ne2n.fsf@vigenere.g10code.de> References: <1403157515.2821.8.camel@cfw2.gniibe.org> <1403168653.2821.9.camel@cfw2.gniibe.org> <1403231035.2376.2.camel@cfw2.gniibe.org> <87a998ne2n.fsf@vigenere.g10code.de> Message-ID: <1403270939.3855.0.camel@latx1.gniibe.org> On 2014-06-20 at 11:08 +0200, Werner Koch wrote: > Can you change the name to mpi_swap_cond ? I would also prefer to keep > it an internal function for now and add it to the public API only > later. This allows to backport it to 1.6. I see. I will. > > To do so, we need to add two more fields in the curve specification: > > co-factor and number of bits of the curve (to set MSB of above code). > > No problem. Thanks. I will do that, too. Another thing to consider is support of new compact representation of draft-jivsov-ecc-compact-05. For Montgomery curve, it doesn't compute y-coordinate, and the representation in my current implementation is: 04 || X || ZERO It works, but it is not correct value (of Y), but I don't think it is worth to compute Y, just for filling. I think that new compact representation (only X) should be the default for Montgomery curve (of ECDH). It is also good to support new compact representation for general ECDH and ECDSA keys. IIUC, draft-jivsov-ecc-compact-05 can be applied to 6637 straightforwardly, and fingerprint (or keygrip) will be different when representation will be changed. Is this right? -- From smueller at chronox.de Sat Jun 21 14:40:13 2014 From: smueller at chronox.de (Stephan Mueller) Date: Sat, 21 Jun 2014 14:40:13 +0200 Subject: [PATCH v3 1/7] SP800-90A Deterministic Random Bit Generator In-Reply-To: <2263776.uX4ZkX09LR@myon.chronox.de> References: <1573675.V5Uuq2JQxy@myon.chronox.de> <2263776.uX4ZkX09LR@myon.chronox.de> Message-ID: <5420916.mHJoDeHKiU@myon.chronox.de> Am Mittwoch, 19. M?rz 2014, 08:35:42 schrieb Stephan Mueller: Hi, after the kernel version of the DRBG is now added to the cryptodev branch maintained by Herbert Xu with the potential to be included into 3.17, the kernel version of the code was subjected to a static code analysis. One potential NULL pointer deference was identified which I ported to the libgcrypt DRBG implementation. diff --git a/random/drbg.c b/random/drbg.c index 2352d1d..703f117 100644 --- a/random/drbg.c +++ b/random/drbg.c @@ -689,14 +689,18 @@ drbg_ctr_df (struct drbg_state *drbg, unsigned char *df_da drbg_string_fill (&S2, L_N, sizeof (L_N)); drbg_string_fill (&S4, pad, padlen); S1.next = &S2; - S2.next = addtl; + + if (NULL == addtl) { + S2.next = &S4; + } else { /* splice in addtl between S2 and S4 -- we place S4 at the end of the * input data chain */ - tempstr = addtl; - for (; NULL != tempstr; tempstr = tempstr->next) - if (NULL == tempstr->next) - break; - tempstr->next = &S4; + S2.next = addtl; + tempstr = addtl; + while (tempstr->next) + tempstr = tempstr->next; + tempstr->next = &S4; + } /* 10.4.2 step 9 */ while (templen < (drbg_keylen (drbg) + (drbg_blocklen (drbg)))) The update will be included in a new patch set, if it is requested. Ciao Stephan -- | Cui bono? | From dbaryshkov at gmail.com Mon Jun 23 17:13:21 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Mon, 23 Jun 2014 19:13:21 +0400 Subject: [PATCH 01/10] GOST R 34.11-94 add OIDs In-Reply-To: <1402080516-8098-1-git-send-email-dbaryshkov@gmail.com> References: <1402080516-8098-1-git-send-email-dbaryshkov@gmail.com> Message-ID: ping On Fri, Jun 6, 2014 at 10:48 PM, Dmitry Eremin-Solenikov wrote: > * cipher/gostr3411-94.c: Add OIDs for GOST R 34.11-94 from RFC 4357. > > Signed-off-by: Dmitry Eremin-Solenikov > --- > cipher/gostr3411-94.c | 15 ++++++++++++++- > 1 file changed, 14 insertions(+), 1 deletion(-) > -- With best wishes Dmitry From jussi.kivilinna at iki.fi Mon Jun 23 18:01:55 2014 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Mon, 23 Jun 2014 19:01:55 +0300 Subject: [PATCH] Poly1305-AEAD: update to match latest Internet-Draft version In-Reply-To: <20140611164412.19049.99544.stgit@localhost6.localdomain6> References: <20140611164412.19049.99544.stgit@localhost6.localdomain6> Message-ID: <53A84F73.1020504@iki.fi> On 11.06.2014 19:44, Jussi Kivilinna wrote: > * cipher/cipher-internal.h (gcry_cipher_handle): Use separate byte > counters for AAD and data in Poly1305. > * cipher/cipher-poly1305.c (poly1305_fill_bytecount): Remove. > (poly1305_fill_bytecounts, poly1305_do_padding): New. > (poly1305_aad_finish): Fill padding to Poly1305 and do not fill AAD > length. > (_gcry_cipher_poly1305_authenticate, _gcry_cipher_poly1305_encrypt) > (_gcry_cipher_poly1305_decrypt): Update AAD and data length separately. > (_gcry_cipher_poly1305_tag): Fill padding and bytecounts to Poly1305. > (_gcry_cipher_poly1305_setkey, _gcry_cipher_poly1305_setiv): Reset > AAD and data byte counts. > * tests/basic.c (_check_poly1305_cipher): Update test-vectors. > -- > > New Internet-Draft version for "ChaCha20 and Poly1305 for IETF protocols" > added padding to Poly1305-AEAD: > http://tools.ietf.org/rfcdiff?url2=draft-nir-cfrg-chacha20-poly1305-04.txt > > Patch makes Poly1305-AEAD implementation to match the changes. I'm having second thoughts about this. The Poly1305-AEAD as now implemented in libgcrypt is already used in (Open)SSH and other places, so it might be good idea to support both the old Poly1305-AEAD and the new. But what would be the best way to select between the two Poly1305-AEAD modes? -Jussi > > Signed-off-by: Jussi Kivilinna > --- > cipher/cipher-internal.h | 7 +++-- > cipher/cipher-poly1305.c | 63 ++++++++++++++++++++++++++++++++------------ > tests/basic.c | 66 ++++++++++++++++++++++++++++++++++------------ > 3 files changed, 100 insertions(+), 36 deletions(-) > > diff --git a/cipher/cipher-internal.h b/cipher/cipher-internal.h > index f6bda66..0e73fde 100644 > --- a/cipher/cipher-internal.h > +++ b/cipher/cipher-internal.h > @@ -159,8 +159,11 @@ struct gcry_cipher_handle > > /* Mode specific storage for Poly1305 mode. */ > struct { > - /* byte counter for AAD and data. */ > - u32 bytecount[2]; > + /* byte counter for AAD. */ > + u32 aadcount[2]; > + > + /* byte counter for data. */ > + u32 datacount[2]; > > unsigned int aad_finalized:1; > unsigned int bytecount_over_limits:1; > diff --git a/cipher/cipher-poly1305.c b/cipher/cipher-poly1305.c > index a22ffa3..e9e063d 100644 > --- a/cipher/cipher-poly1305.c > +++ b/cipher/cipher-poly1305.c > @@ -53,12 +53,14 @@ poly1305_bytecounter_add (u32 ctr[2], size_t add) > > > static void > -poly1305_fill_bytecount (gcry_cipher_hd_t c) > +poly1305_fill_bytecounts (gcry_cipher_hd_t c) > { > - u32 lenbuf[2]; > + u32 lenbuf[4]; > > - lenbuf[0] = le_bswap32(c->u_mode.poly1305.bytecount[0]); > - lenbuf[1] = le_bswap32(c->u_mode.poly1305.bytecount[1]); > + lenbuf[0] = le_bswap32(c->u_mode.poly1305.aadcount[0]); > + lenbuf[1] = le_bswap32(c->u_mode.poly1305.aadcount[1]); > + lenbuf[2] = le_bswap32(c->u_mode.poly1305.datacount[0]); > + lenbuf[3] = le_bswap32(c->u_mode.poly1305.datacount[1]); > _gcry_poly1305_update (&c->u_mode.poly1305.ctx, (byte*)lenbuf, > sizeof(lenbuf)); > > @@ -67,15 +69,33 @@ poly1305_fill_bytecount (gcry_cipher_hd_t c) > > > static void > +poly1305_do_padding (gcry_cipher_hd_t c, u32 ctr[2]) > +{ > + static const byte zero_padding_buf[15] = {}; > + u32 padding_count; > + > + /* Padding to 16 byte boundary. */ > + if (ctr[0] % 16 > 0) > + { > + padding_count = 16 - ctr[0] % 16; > + > + _gcry_poly1305_update (&c->u_mode.poly1305.ctx, zero_padding_buf, > + padding_count); > + } > +} > + > + > +static void > poly1305_aad_finish (gcry_cipher_hd_t c) > { > - /* Start of encryption marks end of AAD stream. */ > - poly1305_fill_bytecount(c); > + /* After AAD, feed padding bytes so we get 16 byte alignment. */ > + poly1305_do_padding (c, c->u_mode.poly1305.aadcount); > > + /* Start of encryption marks end of AAD stream. */ > c->u_mode.poly1305.aad_finalized = 1; > > - c->u_mode.poly1305.bytecount[0] = 0; > - c->u_mode.poly1305.bytecount[1] = 0; > + c->u_mode.poly1305.datacount[0] = 0; > + c->u_mode.poly1305.datacount[1] = 0; > } > > > @@ -102,7 +122,7 @@ _gcry_cipher_poly1305_authenticate (gcry_cipher_hd_t c, > if (!c->marks.iv) > poly1305_set_zeroiv(c); > > - if (poly1305_bytecounter_add(c->u_mode.poly1305.bytecount, aadbuflen)) > + if (poly1305_bytecounter_add(c->u_mode.poly1305.aadcount, aadbuflen)) > { > c->u_mode.poly1305.bytecount_over_limits = 1; > return GPG_ERR_INV_LENGTH; > @@ -138,7 +158,7 @@ _gcry_cipher_poly1305_encrypt (gcry_cipher_hd_t c, > if (!c->u_mode.poly1305.aad_finalized) > poly1305_aad_finish(c); > > - if (poly1305_bytecounter_add(c->u_mode.poly1305.bytecount, inbuflen)) > + if (poly1305_bytecounter_add(c->u_mode.poly1305.datacount, inbuflen)) > { > c->u_mode.poly1305.bytecount_over_limits = 1; > return GPG_ERR_INV_LENGTH; > @@ -176,7 +196,7 @@ _gcry_cipher_poly1305_decrypt (gcry_cipher_hd_t c, > if (!c->u_mode.poly1305.aad_finalized) > poly1305_aad_finish(c); > > - if (poly1305_bytecounter_add(c->u_mode.poly1305.bytecount, inbuflen)) > + if (poly1305_bytecounter_add(c->u_mode.poly1305.datacount, inbuflen)) > { > c->u_mode.poly1305.bytecount_over_limits = 1; > return GPG_ERR_INV_LENGTH; > @@ -212,8 +232,11 @@ _gcry_cipher_poly1305_tag (gcry_cipher_hd_t c, > > if (!c->marks.tag) > { > - /* Write data-length to poly1305. */ > - poly1305_fill_bytecount(c); > + /* After data, feed padding bytes so we get 16 byte alignment. */ > + poly1305_do_padding (c, c->u_mode.poly1305.datacount); > + > + /* Write byte counts to poly1305. */ > + poly1305_fill_bytecounts(c); > > _gcry_poly1305_finish(&c->u_mode.poly1305.ctx, c->u_iv.iv); > > @@ -247,8 +270,11 @@ _gcry_cipher_poly1305_check_tag (gcry_cipher_hd_t c, const unsigned char *intag, > void > _gcry_cipher_poly1305_setkey (gcry_cipher_hd_t c) > { > - c->u_mode.poly1305.bytecount[0] = 0; > - c->u_mode.poly1305.bytecount[1] = 0; > + c->u_mode.poly1305.aadcount[0] = 0; > + c->u_mode.poly1305.aadcount[1] = 0; > + > + c->u_mode.poly1305.datacount[0] = 0; > + c->u_mode.poly1305.datacount[1] = 0; > > c->u_mode.poly1305.bytecount_over_limits = 0; > c->u_mode.poly1305.aad_finalized = 0; > @@ -268,8 +294,11 @@ _gcry_cipher_poly1305_setiv (gcry_cipher_hd_t c, const byte *iv, size_t ivlen) > > memset(&c->u_mode.poly1305.ctx, 0, sizeof(c->u_mode.poly1305.ctx)); > > - c->u_mode.poly1305.bytecount[0] = 0; > - c->u_mode.poly1305.bytecount[1] = 0; > + c->u_mode.poly1305.aadcount[0] = 0; > + c->u_mode.poly1305.aadcount[1] = 0; > + > + c->u_mode.poly1305.datacount[0] = 0; > + c->u_mode.poly1305.datacount[1] = 0; > > c->u_mode.poly1305.bytecount_over_limits = 0; > c->u_mode.poly1305.aad_finalized = 0; > diff --git a/tests/basic.c b/tests/basic.c > index 875b36c..bc18aac 100644 > --- a/tests/basic.c > +++ b/tests/basic.c > @@ -1625,27 +1625,59 @@ _check_poly1305_cipher (unsigned int step) > struct tv > { > int algo; > - char key[MAX_DATA_LEN]; > - char iv[MAX_DATA_LEN]; > + const char *key; > + const char *iv; > int ivlen; > - unsigned char aad[MAX_DATA_LEN]; > + const char *aad; > int aadlen; > - unsigned char plaintext[MAX_DATA_LEN]; > + const char *plaintext; > int inlen; > - char out[MAX_DATA_LEN]; > - char tag[MAX_DATA_LEN]; > + const char *out; > + const char *tag; > } tv[] = > { > - /* draft-agl-tls-chacha20poly1305-04 */ > + /* draft-nir-cfrg-chacha20-poly1305-04 */ > { GCRY_CIPHER_CHACHA20, > - "\x42\x90\xbc\xb1\x54\x17\x35\x31\xf3\x14\xaf\x57\xf3\xbe\x3b\x50" > - "\x06\xda\x37\x1e\xce\x27\x2a\xfa\x1b\x5d\xbd\xd1\x10\x0a\x10\x07", > - "\xcd\x7c\xf6\x7b\xe3\x9c\x79\x4a", 8, > - "\x87\xe2\x29\xd4\x50\x08\x45\xa0\x79\xc0", 10, > - "\x86\xd0\x99\x74\x84\x0b\xde\xd2\xa5\xca", 10, > - "\xe3\xe4\x46\xf7\xed\xe9\xa1\x9b\x62\xa4", > - "\x67\x7d\xab\xf4\xe3\xd2\x4b\x87\x6b\xb2\x84\x75\x38\x96\xe1\xd6" }, > - /* draft-nir-cfrg-chacha20-poly1305-03 */ > + "\x1c\x92\x40\xa5\xeb\x55\xd3\x8a\xf3\x33\x88\x86\x04\xf6\xb5\xf0" > + "\x47\x39\x17\xc1\x40\x2b\x80\x09\x9d\xca\x5c\xbc\x20\x70\x75\xc0", > + "\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08", 12, > + "\xf3\x33\x88\x86\x00\x00\x00\x00\x00\x00\x4e\x91", 12, > + "\x49\x6e\x74\x65\x72\x6e\x65\x74\x2d\x44\x72\x61\x66\x74\x73\x20" > + "\x61\x72\x65\x20\x64\x72\x61\x66\x74\x20\x64\x6f\x63\x75\x6d\x65" > + "\x6e\x74\x73\x20\x76\x61\x6c\x69\x64\x20\x66\x6f\x72\x20\x61\x20" > + "\x6d\x61\x78\x69\x6d\x75\x6d\x20\x6f\x66\x20\x73\x69\x78\x20\x6d" > + "\x6f\x6e\x74\x68\x73\x20\x61\x6e\x64\x20\x6d\x61\x79\x20\x62\x65" > + "\x20\x75\x70\x64\x61\x74\x65\x64\x2c\x20\x72\x65\x70\x6c\x61\x63" > + "\x65\x64\x2c\x20\x6f\x72\x20\x6f\x62\x73\x6f\x6c\x65\x74\x65\x64" > + "\x20\x62\x79\x20\x6f\x74\x68\x65\x72\x20\x64\x6f\x63\x75\x6d\x65" > + "\x6e\x74\x73\x20\x61\x74\x20\x61\x6e\x79\x20\x74\x69\x6d\x65\x2e" > + "\x20\x49\x74\x20\x69\x73\x20\x69\x6e\x61\x70\x70\x72\x6f\x70\x72" > + "\x69\x61\x74\x65\x20\x74\x6f\x20\x75\x73\x65\x20\x49\x6e\x74\x65" > + "\x72\x6e\x65\x74\x2d\x44\x72\x61\x66\x74\x73\x20\x61\x73\x20\x72" > + "\x65\x66\x65\x72\x65\x6e\x63\x65\x20\x6d\x61\x74\x65\x72\x69\x61" > + "\x6c\x20\x6f\x72\x20\x74\x6f\x20\x63\x69\x74\x65\x20\x74\x68\x65" > + "\x6d\x20\x6f\x74\x68\x65\x72\x20\x74\x68\x61\x6e\x20\x61\x73\x20" > + "\x2f\xe2\x80\x9c\x77\x6f\x72\x6b\x20\x69\x6e\x20\x70\x72\x6f\x67" > + "\x72\x65\x73\x73\x2e\x2f\xe2\x80\x9d", 265, > + "\x64\xa0\x86\x15\x75\x86\x1a\xf4\x60\xf0\x62\xc7\x9b\xe6\x43\xbd" > + "\x5e\x80\x5c\xfd\x34\x5c\xf3\x89\xf1\x08\x67\x0a\xc7\x6c\x8c\xb2" > + "\x4c\x6c\xfc\x18\x75\x5d\x43\xee\xa0\x9e\xe9\x4e\x38\x2d\x26\xb0" > + "\xbd\xb7\xb7\x3c\x32\x1b\x01\x00\xd4\xf0\x3b\x7f\x35\x58\x94\xcf" > + "\x33\x2f\x83\x0e\x71\x0b\x97\xce\x98\xc8\xa8\x4a\xbd\x0b\x94\x81" > + "\x14\xad\x17\x6e\x00\x8d\x33\xbd\x60\xf9\x82\xb1\xff\x37\xc8\x55" > + "\x97\x97\xa0\x6e\xf4\xf0\xef\x61\xc1\x86\x32\x4e\x2b\x35\x06\x38" > + "\x36\x06\x90\x7b\x6a\x7c\x02\xb0\xf9\xf6\x15\x7b\x53\xc8\x67\xe4" > + "\xb9\x16\x6c\x76\x7b\x80\x4d\x46\xa5\x9b\x52\x16\xcd\xe7\xa4\xe9" > + "\x90\x40\xc5\xa4\x04\x33\x22\x5e\xe2\x82\xa1\xb0\xa0\x6c\x52\x3e" > + "\xaf\x45\x34\xd7\xf8\x3f\xa1\x15\x5b\x00\x47\x71\x8c\xbc\x54\x6a" > + "\x0d\x07\x2b\x04\xb3\x56\x4e\xea\x1b\x42\x22\x73\xf5\x48\x27\x1a" > + "\x0b\xb2\x31\x60\x53\xfa\x76\x99\x19\x55\xeb\xd6\x31\x59\x43\x4e" > + "\xce\xbb\x4e\x46\x6d\xae\x5a\x10\x73\xa6\x72\x76\x27\x09\x7a\x10" > + "\x49\xe6\x17\xd9\x1d\x36\x10\x94\xfa\x68\xf0\xff\x77\x98\x71\x30" > + "\x30\x5b\xea\xba\x2e\xda\x04\xdf\x99\x7b\x71\x4d\x6c\x6f\x2c\x29" > + "\xa6\xad\x5c\xb4\x02\x2b\x02\x70\x9b", > + "\xee\xad\x9d\x67\x89\x0c\xbb\x22\x39\x23\x36\xfe\xa1\x85\x1f\x38" }, > + /* draft-nir-cfrg-chacha20-poly1305-04 */ > { GCRY_CIPHER_CHACHA20, > "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" > "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f", > @@ -1661,11 +1693,11 @@ _check_poly1305_cipher (unsigned int step) > "\xfa\xb3\x24\xe4\xfa\xd6\x75\x94\x55\x85\x80\x8b\x48\x31\xd7\xbc" > "\x3f\xf4\xde\xf0\x8e\x4b\x7a\x9d\xe5\x76\xd2\x65\x86\xce\xc6\x4b" > "\x61\x16", > - "\x18\xfb\x11\xa5\x03\x1a\xd1\x3a\x7e\x3b\x03\xd4\x6e\xe3\xa6\xa7" } > + "\x1a\xe1\x0b\x59\x4f\x09\xe2\x6a\x7e\x90\x2e\xcb\xd0\x60\x06\x91" }, > }; > > gcry_cipher_hd_t hde, hdd; > - unsigned char out[MAX_DATA_LEN]; > + unsigned char out[1024]; > unsigned char tag[16]; > int i, keylen; > gcry_error_t err = 0; > > > _______________________________________________ > Gcrypt-devel mailing list > Gcrypt-devel at gnupg.org > http://lists.gnupg.org/mailman/listinfo/gcrypt-devel > From smueller at chronox.de Mon Jun 23 18:43:27 2014 From: smueller at chronox.de (Stephan Mueller) Date: Mon, 23 Jun 2014 18:43:27 +0200 Subject: [PATCH v3 1/7] SP800-90A Deterministic Random Bit Generator In-Reply-To: <5420916.mHJoDeHKiU@myon.chronox.de> References: <1573675.V5Uuq2JQxy@myon.chronox.de> <2263776.uX4ZkX09LR@myon.chronox.de> <5420916.mHJoDeHKiU@myon.chronox.de> Message-ID: <17779176.GifnzXNd0B@myon.chronox.de> Am Samstag, 21. Juni 2014, 14:40:13 schrieb Stephan Mueller: Hi, > Am Mittwoch, 19. M?rz 2014, 08:35:42 schrieb Stephan Mueller: > after the kernel version of the DRBG is now added to the cryptodev branch > maintained by Herbert Xu with the potential to be included into 3.17, the > kernel version of the code was subjected to a static code analysis. After careful analysis of the code, the anticipated NULL pointer deference is already caught in drbg_ctr_update which is the only function invoking drbg_ctr_df when addtl is not NULL. Thus I simplified the patch to only make the code for ordering of the linked list in drbg_ctr_df nicer to read. This patch is tested with CAVS testing and the test set provided in [1]. diff --git a/random/drbg.c b/random/drbg.c index 2352d1d..3729428 100644 --- a/random/drbg.c +++ b/random/drbg.c @@ -690,12 +690,13 @@ drbg_ctr_df (struct drbg_state *drbg, unsigned char *df_da drbg_string_fill (&S4, pad, padlen); S1.next = &S2; S2.next = addtl; - /* splice in addtl between S2 and S4 -- we place S4 at the end of the - * input data chain */ + + /* Splice in addtl between S2 and S4 -- we place S4 at the end of the + * input data chain. As this code is only triggered when addtl is not + * NULL, no NULL checks are necessary.*/ tempstr = addtl; - for (; NULL != tempstr; tempstr = tempstr->next) - if (NULL == tempstr->next) - break; + while (tempstr->next) + tempstr = tempstr->next; [1] http://www.chronox.de/drbg.html Ciao Stephan -- | Cui bono? | From wk at gnupg.org Mon Jun 23 18:50:50 2014 From: wk at gnupg.org (Werner Koch) Date: Mon, 23 Jun 2014 18:50:50 +0200 Subject: [PATCH 01/10] GOST R 34.11-94 add OIDs In-Reply-To: (Dmitry Eremin-Solenikov's message of "Mon, 23 Jun 2014 19:13:21 +0400") References: <1402080516-8098-1-git-send-email-dbaryshkov@gmail.com> Message-ID: <87ionrk1sl.fsf@vigenere.g10code.de> On Mon, 23 Jun 2014 17:13, dbaryshkov at gmail.com said: > ping Yeah, I know. Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From wk at gnupg.org Mon Jun 23 18:50:17 2014 From: wk at gnupg.org (Werner Koch) Date: Mon, 23 Jun 2014 18:50:17 +0200 Subject: [PATCH] Poly1305-AEAD: update to match latest Internet-Draft version In-Reply-To: <53A84F73.1020504@iki.fi> (Jussi Kivilinna's message of "Mon, 23 Jun 2014 19:01:55 +0300") References: <20140611164412.19049.99544.stgit@localhost6.localdomain6> <53A84F73.1020504@iki.fi> Message-ID: <87mwd3k1ti.fsf@vigenere.g10code.de> On Mon, 23 Jun 2014 18:01, jussi.kivilinna at iki.fi said: > places, so it might be good idea to support both the old Poly1305-AEAD > and the new. But what would be the best way to select between the two > Poly1305-AEAD modes? We had the same probloem with the TIGER algorithm. Eventually we ended up with 3 algorithm ids to support all variants and implementation bugs. Thus what about: GCRY_MAC_POLY1305X = 501, GCRY_MAC_POLY1305X_AES = 502, GCRY_MAC_POLY1305X_CAMELLIA = 503, GCRY_MAC_POLY1305X_TWOFISH = 504, GCRY_MAC_POLY1305X_SERPENT = 505, GCRY_MAC_POLY1305X_SEED = 506, GCRY_MAC_POLY1305 = 511, GCRY_MAC_POLY1305_AES = 512, GCRY_MAC_POLY1305_CAMELLIA = 513, GCRY_MAC_POLY1305_TWOFISH = 514, GCRY_MAC_POLY1305_SERPENT = 515, GCRY_MAC_POLY1305_SEED = 516 or maybe better "OLD" instead of "X". Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From cvs at cvs.gnupg.org Sat Jun 28 10:52:54 2014 From: cvs at cvs.gnupg.org (by Dmitry Eremin-Solenikov) Date: Sat, 28 Jun 2014 10:52:54 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-93-g066f068 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 066f068bd0bc4d8e01f1f18b6153cdc8d2c245d7 (commit) via 7aeba6c449169926076df83b01ddbfa6b41fe411 (commit) via b78d504fa8745b8b04589acbbcf7dd5fe9279d13 (commit) via 7533b2ad46f42e98d9dba52e88e79c0311d2d3b7 (commit) via 25d6af77e2336b5979ddbe8b90978fe5b61dfaf9 (commit) via 5ee35a04362c94e680ef3633fa83b72e0aee8626 (commit) via fb074d113fcbf66a5c20592625cb19051f3430f5 (commit) via 164738a0292b3f32c7747099ad9cadace58e5eda (commit) via 34a58010000288515636706811c3837f32957b2e (commit) via 8b221cf5ce233c8c49a4e4ecebb70d523fc37837 (commit) from f14fb5b427b5159fcd9603d2b3cde936889cf430 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 066f068bd0bc4d8e01f1f18b6153cdc8d2c245d7 Author: Dmitry Eremin-Solenikov Date: Fri Jun 6 22:48:36 2014 +0400 gostr3411_94: rewrite to use u32 mathematic * cipher/gost28147.c (_gcry_gost_enc_data): New. * cipher/gostr3411-94.c: Rewrite implementation to use u32 mathematic internally. * cipher/gost28147.c (_gcry_gost_enc_one): Remove. -- On my box (Core2 Duo, i386) this highly improves GOST R 34.11-94 speed. Before: GOSTR3411_94 | 55.04 ns/B 17.33 MiB/s - c/B After: GOSTR3411_94 | 36.70 ns/B 25.99 MiB/s - c/B Signed-off-by: Dmitry Eremin-Solenikov diff --git a/cipher/gost.h b/cipher/gost.h index caaf34b..025119c 100644 --- a/cipher/gost.h +++ b/cipher/gost.h @@ -26,7 +26,7 @@ typedef struct { } GOST28147_context; /* This is a simple interface that will be used by GOST R 34.11-94 */ -extern unsigned int _gcry_gost_enc_one (GOST28147_context *c, const byte *key, - byte *out, byte *in, int cryptopro); +unsigned int _gcry_gost_enc_data (GOST28147_context *c, const u32 *key, + u32 *o1, u32 *o2, u32 n1, u32 n2, int cryptopro); #endif diff --git a/cipher/gost28147.c b/cipher/gost28147.c index af3911e..4ff80b4 100644 --- a/cipher/gost28147.c +++ b/cipher/gost28147.c @@ -69,13 +69,9 @@ gost_val (GOST28147_context *ctx, u32 cm1, int subkey) } static unsigned int -gost_encrypt_block (void *c, byte *outbuf, const byte *inbuf) +_gost_encrypt_data (void *c, u32 *o1, u32 *o2, u32 n1, u32 n2) { GOST28147_context *ctx = c; - u32 n1, n2; - - n1 = buf_get_le32 (inbuf); - n2 = buf_get_le32 (inbuf+4); n2 ^= gost_val (ctx, n1, 0); n1 ^= gost_val (ctx, n2, 1); n2 ^= gost_val (ctx, n1, 2); n1 ^= gost_val (ctx, n2, 3); @@ -97,23 +93,41 @@ gost_encrypt_block (void *c, byte *outbuf, const byte *inbuf) n2 ^= gost_val (ctx, n1, 3); n1 ^= gost_val (ctx, n2, 2); n2 ^= gost_val (ctx, n1, 1); n1 ^= gost_val (ctx, n2, 0); - buf_put_le32 (outbuf+0, n2); - buf_put_le32 (outbuf+4, n1); + *o1 = n2; + *o2 = n1; return /* burn_stack */ 4*sizeof(void*) /* func call */ + 3*sizeof(void*) /* stack */ + 4*sizeof(void*) /* gost_val call */; } -unsigned int _gcry_gost_enc_one (GOST28147_context *c, const byte *key, - byte *out, byte *in, int cryptopro) +static unsigned int +gost_encrypt_block (void *c, byte *outbuf, const byte *inbuf) +{ + GOST28147_context *ctx = c; + u32 n1, n2; + unsigned int burn; + + n1 = buf_get_le32 (inbuf); + n2 = buf_get_le32 (inbuf+4); + + burn = _gost_encrypt_data(ctx, &n1, &n2, n1, n2); + + buf_put_le32 (outbuf+0, n1); + buf_put_le32 (outbuf+4, n2); + + return /* burn_stack */ burn + 6*sizeof(void*) /* func call */; +} + +unsigned int _gcry_gost_enc_data (GOST28147_context *c, const u32 *key, + u32 *o1, u32 *o2, u32 n1, u32 n2, int cryptopro) { if (cryptopro) c->sbox = sbox_CryptoPro_3411; else c->sbox = sbox_test_3411; - gost_setkey (c, key, 32); - return gost_encrypt_block (c, out, in) + 5 * sizeof(void *); + memcpy (c->key, key, 8*4); + return _gost_encrypt_data (c, o1, o2, n1, n2) + 7 * sizeof(void *); } static unsigned int diff --git a/cipher/gostr3411-94.c b/cipher/gostr3411-94.c index 9d065fb..91e5b4c 100644 --- a/cipher/gostr3411-94.c +++ b/cipher/gostr3411-94.c @@ -25,6 +25,7 @@ #include "g10lib.h" #include "bithelp.h" +#include "bufhelp.h" #include "cipher.h" #include "hash-common.h" @@ -35,8 +36,11 @@ typedef struct { gcry_md_block_ctx_t bctx; GOST28147_context hd; - byte h[32]; - byte sigma[32]; + union { + u32 h[8]; + byte result[32]; + }; + u32 sigma[8]; u32 len; int cryptopro; } GOSTR3411_CONTEXT; @@ -71,102 +75,122 @@ gost3411_cp_init (void *context, unsigned int flags) } static void -do_p (unsigned char *p, unsigned char *u, unsigned char *v) +do_p (u32 *p, u32 *u, u32 *v) { - int i, k; + int k; + u32 t[8]; + for (k = 0; k < 8; k++) + t[k] = u[k] ^ v[k]; + + for (k = 0; k < 4; k++) { - for (i = 0; i < 4; i++) - { - p[i + 4 * k] = u[8 * i + k] ^ v[8 * i + k]; - } + p[k+0] = ((t[0] >> (8*k)) & 0xff) << 0 | + ((t[2] >> (8*k)) & 0xff) << 8 | + ((t[4] >> (8*k)) & 0xff) << 16 | + ((t[6] >> (8*k)) & 0xff) << 24; + p[k+4] = ((t[1] >> (8*k)) & 0xff) << 0 | + ((t[3] >> (8*k)) & 0xff) << 8 | + ((t[5] >> (8*k)) & 0xff) << 16 | + ((t[7] >> (8*k)) & 0xff) << 24; } } static void -do_a (unsigned char *u) +do_a (u32 *u) { - unsigned char temp[8]; + u32 t[2]; int i; - memcpy (temp, u, 8); - memmove (u, u+8, 24); - for (i = 0; i < 8; i++) - { - u[24 + i] = u[i] ^ temp[i]; - } + memcpy(t, u, 2*4); + for (i = 0; i < 6; i++) + u[i] = u[i+2]; + u[6] = u[0] ^ t[0]; + u[7] = u[1] ^ t[1]; } /* apply do_a twice: 1 2 3 4 -> 3 4 1^2 2^3 */ static void -do_a2 (unsigned char *u) +do_a2 (u32 *u) { - unsigned char temp[16]; + u32 t[4]; int i; - memcpy (temp, u, 16); - memcpy (u, u + 16, 16); - for (i = 0; i < 8; i++) + memcpy (t, u, 16); + memcpy (u, u + 4, 16); + for (i = 0; i < 2; i++) { - u[16 + i] = temp[i] ^ temp[8 + i]; - u[24 + i] = u[i] ^ temp[8 + i]; + u[4+i] = t[i] ^ t[i + 2]; + u[6+i] = u[i] ^ t[i + 2]; } } static void -do_apply_c2 (unsigned char *u) +do_apply_c2 (u32 *u) { - u[ 1] ^= 0xff; - u[ 3] ^= 0xff; - u[ 5] ^= 0xff; - u[ 7] ^= 0xff; - - u[ 8] ^= 0xff; - u[10] ^= 0xff; - u[12] ^= 0xff; - u[14] ^= 0xff; - - u[17] ^= 0xff; - u[18] ^= 0xff; - u[20] ^= 0xff; - u[23] ^= 0xff; - - u[24] ^= 0xff; - u[28] ^= 0xff; - u[29] ^= 0xff; - u[31] ^= 0xff; + u[ 0] ^= 0xff00ff00; + u[ 1] ^= 0xff00ff00; + u[ 2] ^= 0x00ff00ff; + u[ 3] ^= 0x00ff00ff; + u[ 4] ^= 0x00ffff00; + u[ 5] ^= 0xff0000ff; + u[ 6] ^= 0x000000ff; + u[ 7] ^= 0xff00ffff; } -#define do_phi_step(e, i) \ - e[(0 + 2*i) % 32] ^= e[(2 + 2*i) % 32] ^ e[(4 + 2*i) % 32] ^ e[(6 + 2*i) % 32] ^ e[(24 + 2*i) % 32] ^ e[(30 + 2*i) % 32]; \ - e[(1 + 2*i) % 32] ^= e[(3 + 2*i) % 32] ^ e[(5 + 2*i) % 32] ^ e[(7 + 2*i) % 32] ^ e[(25 + 2*i) % 32] ^ e[(31 + 2*i) % 32]; +#define do_chi_step12(e) \ + e[6] ^= ((e[6] >> 16) ^ e[7] ^ (e[7] >> 16) ^ e[4] ^ (e[5] >>16)) & 0xffff; + +#define do_chi_step13(e) \ + e[6] ^= ((e[7] ^ (e[7] >> 16) ^ e[0] ^ (e[4] >> 16) ^ e[6]) & 0xffff) << 16; + +#define do_chi_doublestep(e, i) \ + e[i] ^= (e[i] >> 16) ^ (e[(i+1)%8] << 16) ^ e[(i+1)%8] ^ (e[(i+1)%8] >> 16) ^ (e[(i+2)%8] << 16) ^ e[(i+6)%8] ^ (e[(i+7)%8] >> 16); \ + e[i] ^= (e[i] << 16); static void -do_phi_submix (unsigned char *e, unsigned char *x, int round) +do_chi_submix12 (u32 *e, u32 *x) { - int i; - round *= 2; - for (i = 0; i < 32; i++) - { - e[(i + round) % 32] ^= x[i]; - } + e[6] ^= x[0]; + e[7] ^= x[1]; + e[0] ^= x[2]; + e[1] ^= x[3]; + e[2] ^= x[4]; + e[3] ^= x[5]; + e[4] ^= x[6]; + e[5] ^= x[7]; +} + +static void +do_chi_submix13 (u32 *e, u32 *x) +{ + e[6] ^= (x[0] << 16) | (x[7] >> 16); + e[7] ^= (x[1] << 16) | (x[0] >> 16); + e[0] ^= (x[2] << 16) | (x[1] >> 16); + e[1] ^= (x[3] << 16) | (x[2] >> 16); + e[2] ^= (x[4] << 16) | (x[3] >> 16); + e[3] ^= (x[5] << 16) | (x[4] >> 16); + e[4] ^= (x[6] << 16) | (x[5] >> 16); + e[5] ^= (x[7] << 16) | (x[6] >> 16); } static void -do_add (unsigned char *s, unsigned char *a) +do_add (u32 *s, u32 *a) { - unsigned temp = 0; + u32 carry = 0; int i; - for (i = 0; i < 32; i++) + for (i = 0; i < 8; i++) { - temp = s[i] + a[i] + (temp >> 8); - s[i] = temp & 0xff; + u32 op = carry + a[i]; + s[i] += op; + carry = (a[i] > op) || (op > s[i]); } } static unsigned int -do_hash_step (GOSTR3411_CONTEXT *hd, unsigned char *h, unsigned char *m) +do_hash_step (GOSTR3411_CONTEXT *hd, u32 *h, u32 *m) { - unsigned char u[32], v[32], s[32]; - unsigned char k[32]; + u32 u[8], v[8]; + u32 s[8]; + u32 k[8]; unsigned int burn; int i; @@ -176,7 +200,7 @@ do_hash_step (GOSTR3411_CONTEXT *hd, unsigned char *h, unsigned char *m) for (i = 0; i < 4; i++) { do_p (k, u, v); - burn = _gcry_gost_enc_one (&hd->hd, k, s + i*8, h + i*8, hd->cryptopro); + burn = _gcry_gost_enc_data (&hd->hd, k, &s[2*i], &s[2*i+1], h[2*i], h[2*i+1], hd->cryptopro); do_a (u); if (i == 1) @@ -186,33 +210,26 @@ do_hash_step (GOSTR3411_CONTEXT *hd, unsigned char *h, unsigned char *m) for (i = 0; i < 5; i++) { - do_phi_step (s, 0); - do_phi_step (s, 1); - do_phi_step (s, 2); - do_phi_step (s, 3); - do_phi_step (s, 4); - do_phi_step (s, 5); - do_phi_step (s, 6); - do_phi_step (s, 7); - do_phi_step (s, 8); - do_phi_step (s, 9); + do_chi_doublestep (s, 0); + do_chi_doublestep (s, 1); + do_chi_doublestep (s, 2); + do_chi_doublestep (s, 3); + do_chi_doublestep (s, 4); /* That is in total 12 + 1 + 61 = 74 = 16 * 4 + 10 rounds */ if (i == 4) break; - do_phi_step (s, 10); - do_phi_step (s, 11); + do_chi_doublestep (s, 5); if (i == 0) - do_phi_submix(s, m, 12); - do_phi_step (s, 12); + do_chi_submix12(s, m); + do_chi_step12 (s); if (i == 0) - do_phi_submix(s, h, 13); - do_phi_step (s, 13); - do_phi_step (s, 14); - do_phi_step (s, 15); + do_chi_submix13(s, h); + do_chi_step13 (s); + do_chi_doublestep (s, 7); } - memcpy (h, s+20, 12); - memcpy (h+12, s, 20); + memcpy (h, s+5, 12); + memcpy (h+3, s, 20); return /* burn_stack */ 4 * sizeof(void*) /* func call (ret addr + args) */ + 4 * 32 + 2 * sizeof(int) /* stack */ + @@ -221,15 +238,16 @@ do_hash_step (GOSTR3411_CONTEXT *hd, unsigned char *h, unsigned char *m) 16 + sizeof(int) /* do_a2 stack */ ); } - static unsigned int transform_blk (void *ctx, const unsigned char *data) { GOSTR3411_CONTEXT *hd = ctx; - byte m[32]; + u32 m[8]; unsigned int burn; + int i; - memcpy (m, data, 32); + for (i = 0; i < 8; i++) + m[i] = buf_get_le32(data + i*4); burn = do_hash_step (hd, hd->h, m); do_add (hd->sigma, m); @@ -263,9 +281,9 @@ gost3411_final (void *context) { GOSTR3411_CONTEXT *hd = context; size_t padlen = 0; - byte l[32]; + u32 l[8]; int i; - u32 nblocks; + MD_NBLOCKS_TYPE nblocks; if (hd->bctx.count > 0) { @@ -286,15 +304,19 @@ gost3411_final (void *context) nblocks --; l[0] = 256 - padlen * 8; } + l[0] |= nblocks << 8; + nblocks >>= 24; for (i = 1; i < 32 && nblocks != 0; i++) { - l[i] = nblocks % 256; - nblocks /= 256; + l[i] = nblocks; + nblocks >>= 24; } do_hash_step (hd, hd->h, l); do_hash_step (hd, hd->h, hd->sigma); + for (i = 0; i < 8; i++) + hd->h[i] = le_bswap32(hd->h[i]); } static byte * @@ -302,7 +324,7 @@ gost3411_read (void *context) { GOSTR3411_CONTEXT *hd = context; - return hd->h; + return hd->result; } static unsigned char asn[6] = /* Object ID is 1.2.643.2.2.3 */ commit 7aeba6c449169926076df83b01ddbfa6b41fe411 Author: Dmitry Eremin-Solenikov Date: Fri Jun 6 22:48:35 2014 +0400 gost28147: use bufhelp helpers * cipher/gost28147.c (gost_setkey, gost_encrypt_block, gost_decrypt_block): use buf_get_le32/buf_put_le32 helpers. -- On my box this boosts GOST 28147-89 speed from 36 MiB/s up to 44.5 MiB/s. Signed-off-by: Dmitry Eremin-Solenikov diff --git a/cipher/gost28147.c b/cipher/gost28147.c index 5456053..af3911e 100644 --- a/cipher/gost28147.c +++ b/cipher/gost28147.c @@ -33,6 +33,7 @@ #include "types.h" #include "g10lib.h" #include "cipher.h" +#include "bufhelp.h" #include "gost.h" #include "gost-sb.h" @@ -51,10 +52,7 @@ gost_setkey (void *c, const byte *key, unsigned keylen) for (i = 0; i < 8; i++) { - ctx->key[i] = (key[4 * i + 3] << 24) | - (key[4 * i + 2] << 16) | - (key[4 * i + 1] << 8) | - (key[4 * i + 0] << 0); + ctx->key[i] = buf_get_le32(&key[4*i]); } return GPG_ERR_NO_ERROR; } @@ -76,14 +74,8 @@ gost_encrypt_block (void *c, byte *outbuf, const byte *inbuf) GOST28147_context *ctx = c; u32 n1, n2; - n1 = (inbuf[0] << 0) | - (inbuf[1] << 8) | - (inbuf[2] << 16) | - (inbuf[3] << 24); - n2 = (inbuf[4] << 0) | - (inbuf[5] << 8) | - (inbuf[6] << 16) | - (inbuf[7] << 24); + n1 = buf_get_le32 (inbuf); + n2 = buf_get_le32 (inbuf+4); n2 ^= gost_val (ctx, n1, 0); n1 ^= gost_val (ctx, n2, 1); n2 ^= gost_val (ctx, n1, 2); n1 ^= gost_val (ctx, n2, 3); @@ -105,14 +97,8 @@ gost_encrypt_block (void *c, byte *outbuf, const byte *inbuf) n2 ^= gost_val (ctx, n1, 3); n1 ^= gost_val (ctx, n2, 2); n2 ^= gost_val (ctx, n1, 1); n1 ^= gost_val (ctx, n2, 0); - outbuf[0 + 0] = (n2 >> (0 * 8)) & 0xff; - outbuf[1 + 0] = (n2 >> (1 * 8)) & 0xff; - outbuf[2 + 0] = (n2 >> (2 * 8)) & 0xff; - outbuf[3 + 0] = (n2 >> (3 * 8)) & 0xff; - outbuf[0 + 4] = (n1 >> (0 * 8)) & 0xff; - outbuf[1 + 4] = (n1 >> (1 * 8)) & 0xff; - outbuf[2 + 4] = (n1 >> (2 * 8)) & 0xff; - outbuf[3 + 4] = (n1 >> (3 * 8)) & 0xff; + buf_put_le32 (outbuf+0, n2); + buf_put_le32 (outbuf+4, n1); return /* burn_stack */ 4*sizeof(void*) /* func call */ + 3*sizeof(void*) /* stack */ + @@ -136,14 +122,8 @@ gost_decrypt_block (void *c, byte *outbuf, const byte *inbuf) GOST28147_context *ctx = c; u32 n1, n2; - n1 = (inbuf[0] << 0) | - (inbuf[1] << 8) | - (inbuf[2] << 16) | - (inbuf[3] << 24); - n2 = (inbuf[4] << 0) | - (inbuf[5] << 8) | - (inbuf[6] << 16) | - (inbuf[7] << 24); + n1 = buf_get_le32 (inbuf); + n2 = buf_get_le32 (inbuf+4); n2 ^= gost_val (ctx, n1, 0); n1 ^= gost_val (ctx, n2, 1); n2 ^= gost_val (ctx, n1, 2); n1 ^= gost_val (ctx, n2, 3); @@ -165,14 +145,8 @@ gost_decrypt_block (void *c, byte *outbuf, const byte *inbuf) n2 ^= gost_val (ctx, n1, 3); n1 ^= gost_val (ctx, n2, 2); n2 ^= gost_val (ctx, n1, 1); n1 ^= gost_val (ctx, n2, 0); - outbuf[0 + 0] = (n2 >> (0 * 8)) & 0xff; - outbuf[1 + 0] = (n2 >> (1 * 8)) & 0xff; - outbuf[2 + 0] = (n2 >> (2 * 8)) & 0xff; - outbuf[3 + 0] = (n2 >> (3 * 8)) & 0xff; - outbuf[0 + 4] = (n1 >> (0 * 8)) & 0xff; - outbuf[1 + 4] = (n1 >> (1 * 8)) & 0xff; - outbuf[2 + 4] = (n1 >> (2 * 8)) & 0xff; - outbuf[3 + 4] = (n1 >> (3 * 8)) & 0xff; + buf_put_le32 (outbuf+0, n2); + buf_put_le32 (outbuf+4, n1); return /* burn_stack */ 4*sizeof(void*) /* func call */ + 3*sizeof(void*) /* stack */ + commit b78d504fa8745b8b04589acbbcf7dd5fe9279d13 Author: Dmitry Eremin-Solenikov Date: Fri Jun 6 22:48:34 2014 +0400 Fixup curve name in the GOST2012 test case * tests/basic.c (check_pubkey): fixup curve name in public key. Signed-off-by: Dmitry Eremin-Solenikov diff --git a/tests/basic.c b/tests/basic.c index 875b36c..6d70cfd 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -6966,7 +6966,7 @@ check_pubkey (void) "(public-key\n" " (ecc\n" - " (curve GOST2001-test)\n" + " (curve GOST2012-test)\n" " (q #04115DC5BC96760C7B48598D8AB9E740D4C4A85A65BE33C1" " 815B5C320C854621DD5A515856D13314AF69BC5B924C8B" " 4DDFF75C45415C1D9DD9DD33612CD530EFE137C7C90CD4" commit 7533b2ad46f42e98d9dba52e88e79c0311d2d3b7 Author: Dmitry Eremin-Solenikov Date: Fri Jun 6 22:48:33 2014 +0400 Update PBKDF2 tests with GOST R 34.11-94 test cases * tests/t-kdf.c (check_pbkdf2): Add MD_GOSTR3411_CP test cases. -- TC26 (Technical Comitee for standardization "Cryptography and security mechanisms") published a document with test vectors for PBKDF2 used with GOST R 34.11-94 message digest function. Signed-off-by: Dmitry Eremin-Solenikov diff --git a/tests/t-kdf.c b/tests/t-kdf.c index adbe6cc..8e728d5 100644 --- a/tests/t-kdf.c +++ b/tests/t-kdf.c @@ -864,6 +864,7 @@ check_pbkdf2 (void) size_t plen; /* Length of P. */ const char *salt; size_t saltlen; + int hashalgo; unsigned long c; /* Iterations. */ int dklen; /* Requested key length. */ const char *dk; /* Derived key. */ @@ -872,6 +873,7 @@ check_pbkdf2 (void) { "password", 8, "salt", 4, + GCRY_MD_SHA1, 1, 20, "\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9" @@ -880,6 +882,7 @@ check_pbkdf2 (void) { "password", 8, "salt", 4, + GCRY_MD_SHA1, 2, 20, "\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c\xcd\x1e" @@ -888,6 +891,7 @@ check_pbkdf2 (void) { "password", 8, "salt", 4, + GCRY_MD_SHA1, 4096, 20, "\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad" @@ -896,6 +900,7 @@ check_pbkdf2 (void) { "password", 8, "salt", 4, + GCRY_MD_SHA1, 16777216, 20, "\xee\xfe\x3d\x61\xcd\x4d\xa4\xe4\xe9\x94" @@ -905,6 +910,7 @@ check_pbkdf2 (void) { "passwordPASSWORDpassword", 24, "saltSALTsaltSALTsaltSALTsaltSALTsalt", 36, + GCRY_MD_SHA1, 4096, 25, "\x3d\x2e\xec\x4f\xe4\x1c\x84\x9b\x80\xc8" @@ -914,6 +920,7 @@ check_pbkdf2 (void) { "pass\0word", 9, "sa\0lt", 5, + GCRY_MD_SHA1, 4096, 16, "\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37" @@ -922,15 +929,71 @@ check_pbkdf2 (void) { /* empty password test, not in RFC-6070 */ "", 0, "salt", 4, + GCRY_MD_SHA1, 2, 20, "\x13\x3a\x4c\xe8\x37\xb4\xd2\x52\x1e\xe2" "\xbf\x03\xe1\x1c\x71\xca\x79\x4e\x07\x97" + }, + { + "password", 8, + "salt", 4, + GCRY_MD_GOSTR3411_CP, + 1, + 32, + "\x73\x14\xe7\xc0\x4f\xb2\xe6\x62\xc5\x43\x67\x42\x53\xf6\x8b\xd0" + "\xb7\x34\x45\xd0\x7f\x24\x1b\xed\x87\x28\x82\xda\x21\x66\x2d\x58" + }, + { + "password", 8, + "salt", 4, + GCRY_MD_GOSTR3411_CP, + 2, + 32, + "\x99\x0d\xfa\x2b\xd9\x65\x63\x9b\xa4\x8b\x07\xb7\x92\x77\x5d\xf7" + "\x9f\x2d\xb3\x4f\xef\x25\xf2\x74\x37\x88\x72\xfe\xd7\xed\x1b\xb3" + }, + { + "password", 8, + "salt", 4, + GCRY_MD_GOSTR3411_CP, + 4096, + 32, + "\x1f\x18\x29\xa9\x4b\xdf\xf5\xbe\x10\xd0\xae\xb3\x6a\xf4\x98\xe7" + "\xa9\x74\x67\xf3\xb3\x11\x16\xa5\xa7\xc1\xaf\xff\x9d\xea\xda\xfe" + }, + /* { -- takes too long (4-5 min) to calculate + "password", 8, + "salt", 4, + GCRY_MD_GOSTR3411_CP, + 16777216, + 32, + "\xa5\x7a\xe5\xa6\x08\x83\x96\xd1\x20\x85\x0c\x5c\x09\xde\x0a\x52" + "\x51\x00\x93\x8a\x59\xb1\xb5\xc3\xf7\x81\x09\x10\xd0\x5f\xcd\x97" + }, */ + { + "passwordPASSWORDpassword", 24, + "saltSALTsaltSALTsaltSALTsaltSALTsalt", 36, + GCRY_MD_GOSTR3411_CP, + 4096, + 40, + "\x78\x83\x58\xc6\x9c\xb2\xdb\xe2\x51\xa7\xbb\x17\xd5\xf4\x24\x1f" + "\x26\x5a\x79\x2a\x35\xbe\xcd\xe8\xd5\x6f\x32\x6b\x49\xc8\x50\x47" + "\xb7\x63\x8a\xcb\x47\x64\xb1\xfd" + }, + { + "pass\0word", 9, + "sa\0lt", 5, + GCRY_MD_GOSTR3411_CP, + 4096, + 20, + "\x43\xe0\x6c\x55\x90\xb0\x8c\x02\x25\x24" + "\x23\x73\x12\x7e\xdf\x9c\x8e\x9c\x32\x91" } }; int tvidx; gpg_error_t err; - unsigned char outbuf[32]; + unsigned char outbuf[40]; int i; for (tvidx=0; tvidx < DIM(tv); tvidx++) @@ -938,10 +1001,11 @@ check_pbkdf2 (void) if (tv[tvidx].disabled) continue; if (verbose) - fprintf (stderr, "checking PBKDF2 test vector %d\n", tvidx); + fprintf (stderr, "checking PBKDF2 test vector %d algo %d\n", tvidx, + tv[tvidx].hashalgo); assert (tv[tvidx].dklen <= sizeof outbuf); err = gcry_kdf_derive (tv[tvidx].p, tv[tvidx].plen, - GCRY_KDF_PBKDF2, GCRY_MD_SHA1, + GCRY_KDF_PBKDF2, tv[tvidx].hashalgo, tv[tvidx].salt, tv[tvidx].saltlen, tv[tvidx].c, tv[tvidx].dklen, outbuf); if (err) commit 25d6af77e2336b5979ddbe8b90978fe5b61dfaf9 Author: Dmitry Eremin-Solenikov Date: Fri Jun 6 22:48:32 2014 +0400 Add GOST R 34.11-94 variant using id-GostR3411-94-CryptoProParamSet * src/gcrypt.h.in (GCRY_MD_GOSTR3411_CP): New. * src/cipher.h (_gcry_digest_spec_gost3411_cp): New. * cipher/gost28147.c (_gcry_gost_enc_one): Differentiate between CryptoPro and Test S-Boxes. * cipher/gostr3411-94.c (_gcry_digest_spec_gost3411_cp, gost3411_cp_init): New. * cipher/md.c (md_open): GCRY_MD_GOSTR3411_CP also uses B=32. -- RFC4357 defines only two S-Boxes that should be used together with GOST R 34.11-94 - a testing one (from standard itself, for testing only) and CryptoPro one. Instead of adding a separate gcry_md_ctrl() function just to switch s-boxes, add a separate MD algorithm using CryptoPro S-box. Signed-off-by: Dmitry Eremin-Solenikov diff --git a/NEWS b/NEWS index 5eacf30..214c676 100644 --- a/NEWS +++ b/NEWS @@ -28,6 +28,7 @@ Noteworthy changes in version 1.7.0 (unreleased) GCRY_MD_FLAG_BUGEMU1 NEW. GCRYCTL_SET_SBOX NEW. gcry_cipher_set_sbox NEW macro. + GCRY_MD_GOSTR3411_CP NEW. Noteworthy changes in version 1.6.0 (2013-12-16) diff --git a/cipher/gost.h b/cipher/gost.h index 3fbd9df..caaf34b 100644 --- a/cipher/gost.h +++ b/cipher/gost.h @@ -27,6 +27,6 @@ typedef struct { /* This is a simple interface that will be used by GOST R 34.11-94 */ extern unsigned int _gcry_gost_enc_one (GOST28147_context *c, const byte *key, - byte *out, byte *in); + byte *out, byte *in, int cryptopro); #endif diff --git a/cipher/gost28147.c b/cipher/gost28147.c index ae9e705..5456053 100644 --- a/cipher/gost28147.c +++ b/cipher/gost28147.c @@ -120,8 +120,12 @@ gost_encrypt_block (void *c, byte *outbuf, const byte *inbuf) } unsigned int _gcry_gost_enc_one (GOST28147_context *c, const byte *key, - byte *out, byte *in) + byte *out, byte *in, int cryptopro) { + if (cryptopro) + c->sbox = sbox_CryptoPro_3411; + else + c->sbox = sbox_test_3411; gost_setkey (c, key, 32); return gost_encrypt_block (c, out, in) + 5 * sizeof(void *); } diff --git a/cipher/gostr3411-94.c b/cipher/gostr3411-94.c index 73d570f..9d065fb 100644 --- a/cipher/gostr3411-94.c +++ b/cipher/gostr3411-94.c @@ -38,6 +38,7 @@ typedef struct { byte h[32]; byte sigma[32]; u32 len; + int cryptopro; } GOSTR3411_CONTEXT; static unsigned int @@ -58,6 +59,15 @@ gost3411_init (void *context, unsigned int flags) hd->bctx.count = 0; hd->bctx.blocksize = 32; hd->bctx.bwrite = transform; + hd->cryptopro = 0; +} + +static void +gost3411_cp_init (void *context, unsigned int flags) +{ + GOSTR3411_CONTEXT *hd = context; + gost3411_init (context, flags); + hd->cryptopro = 1; } static void @@ -153,7 +163,7 @@ do_add (unsigned char *s, unsigned char *a) } static unsigned int -do_hash_step (GOST28147_context *hd, unsigned char *h, unsigned char *m) +do_hash_step (GOSTR3411_CONTEXT *hd, unsigned char *h, unsigned char *m) { unsigned char u[32], v[32], s[32]; unsigned char k[32]; @@ -166,7 +176,7 @@ do_hash_step (GOST28147_context *hd, unsigned char *h, unsigned char *m) for (i = 0; i < 4; i++) { do_p (k, u, v); - burn = _gcry_gost_enc_one (hd, k, s + i*8, h + i*8); + burn = _gcry_gost_enc_one (&hd->hd, k, s + i*8, h + i*8, hd->cryptopro); do_a (u); if (i == 1) @@ -220,7 +230,7 @@ transform_blk (void *ctx, const unsigned char *data) unsigned int burn; memcpy (m, data, 32); - burn = do_hash_step (&hd->hd, hd->h, m); + burn = do_hash_step (hd, hd->h, m); do_add (hd->sigma, m); return /* burn_stack */ burn + 3 * sizeof(void*) + 32 + 2 * sizeof(void*); @@ -283,8 +293,8 @@ gost3411_final (void *context) nblocks /= 256; } - do_hash_step (&hd->hd, hd->h, l); - do_hash_step (&hd->hd, hd->h, hd->sigma); + do_hash_step (hd, hd->h, l); + do_hash_step (hd, hd->h, hd->sigma); } static byte * @@ -310,7 +320,14 @@ static gcry_md_oid_spec_t oid_spec_gostr3411[] = gcry_md_spec_t _gcry_digest_spec_gost3411_94 = { GCRY_MD_GOSTR3411_94, {0, 0}, - "GOSTR3411_94", asn, DIM (asn), oid_spec_gostr3411, 32, + "GOSTR3411_94", NULL, 0, NULL, 32, gost3411_init, _gcry_md_block_write, gost3411_final, gost3411_read, sizeof (GOSTR3411_CONTEXT) }; +gcry_md_spec_t _gcry_digest_spec_gost3411_cp = + { + GCRY_MD_GOSTR3411_CP, {0, 0}, + "GOSTR3411_CP", asn, DIM (asn), oid_spec_gostr3411, 32, + gost3411_cp_init, _gcry_md_block_write, gost3411_final, gost3411_read, + sizeof (GOSTR3411_CONTEXT) + }; diff --git a/cipher/md.c b/cipher/md.c index 5ab89cb..a1e5859 100644 --- a/cipher/md.c +++ b/cipher/md.c @@ -53,6 +53,7 @@ static gcry_md_spec_t *digest_list[] = #endif #ifdef USE_GOST_R_3411_94 &_gcry_digest_spec_gost3411_94, + &_gcry_digest_spec_gost3411_cp, #endif #ifdef USE_GOST_R_3411_12 &_gcry_digest_spec_stribog_256, @@ -335,6 +336,7 @@ md_open (gcry_md_hd_t *h, int algo, unsigned int flags) ctx->macpads_Bsize = 128; break; case GCRY_MD_GOSTR3411_94: + case GCRY_MD_GOSTR3411_CP: ctx->macpads_Bsize = 32; break; default: diff --git a/src/cipher.h b/src/cipher.h index ed57d3c..f4f6cc4 100644 --- a/src/cipher.h +++ b/src/cipher.h @@ -258,6 +258,7 @@ extern gcry_md_spec_t _gcry_digest_spec_crc32; extern gcry_md_spec_t _gcry_digest_spec_crc32_rfc1510; extern gcry_md_spec_t _gcry_digest_spec_crc24_rfc2440; extern gcry_md_spec_t _gcry_digest_spec_gost3411_94; +extern gcry_md_spec_t _gcry_digest_spec_gost3411_cp; extern gcry_md_spec_t _gcry_digest_spec_stribog_256; extern gcry_md_spec_t _gcry_digest_spec_stribog_512; extern gcry_md_spec_t _gcry_digest_spec_md2; diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index 95d324b..a5f8350 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -1152,7 +1152,8 @@ enum gcry_md_algos GCRY_MD_TIGER2 = 307, /* TIGER2 variant. */ GCRY_MD_GOSTR3411_94 = 308, /* GOST R 34.11-94. */ GCRY_MD_STRIBOG256 = 309, /* GOST R 34.11-2012, 256 bit. */ - GCRY_MD_STRIBOG512 = 310 /* GOST R 34.11-2012, 512 bit. */ + GCRY_MD_STRIBOG512 = 310, /* GOST R 34.11-2012, 512 bit. */ + GCRY_MD_GOSTR3411_CP = 311 /* GOST R 34.11-94 with CryptoPro-A S-Box. */ }; /* Flags used with the open function. */ commit 5ee35a04362c94e680ef3633fa83b72e0aee8626 Author: Dmitry Eremin-Solenikov Date: Fri Jun 6 22:48:31 2014 +0400 gost28147: support GCRYCTL_SET_SBOX cipher/gost28147.c (gost_set_extra_info, gost_set_sbox): New. Signed-off-by: Dmitry Eremin-Solenikov diff --git a/cipher/gost28147.c b/cipher/gost28147.c index 1720f45..ae9e705 100644 --- a/cipher/gost28147.c +++ b/cipher/gost28147.c @@ -175,6 +175,44 @@ gost_decrypt_block (void *c, byte *outbuf, const byte *inbuf) 4*sizeof(void*) /* gost_val call */; } +static gpg_err_code_t +gost_set_sbox (GOST28147_context *ctx, const char *oid) +{ + int i; + + for (i = 0; gost_oid_map[i].oid; i++) + { + if (!strcmp(gost_oid_map[i].oid, oid)) + { + ctx->sbox = gost_oid_map[i].sbox; + return 0; + } + } + return GPG_ERR_VALUE_NOT_FOUND; +} + +static gpg_err_code_t +gost_set_extra_info (void *c, int what, const void *buffer, size_t buflen) +{ + GOST28147_context *ctx = c; + gpg_err_code_t ec = 0; + + (void)buffer; + (void)buflen; + + switch (what) + { + case GCRYCTL_SET_SBOX: + ec = gost_set_sbox (ctx, buffer); + break; + + default: + ec = GPG_ERR_INV_OP; + break; + } + return ec; +} + static gcry_cipher_oid_spec_t oids_gost28147[] = { /* { "1.2.643.2.2.31.0", GCRY_CIPHER_MODE_CNTGOST }, */ @@ -193,4 +231,5 @@ gcry_cipher_spec_t _gcry_cipher_spec_gost28147 = gost_setkey, gost_encrypt_block, gost_decrypt_block, + NULL, NULL, NULL, gost_set_extra_info, }; commit fb074d113fcbf66a5c20592625cb19051f3430f5 Author: Dmitry Eremin-Solenikov Date: Fri Jun 6 22:48:30 2014 +0400 Support setting s-box for the ciphers that require it * src/gcrypt.h.in (GCRYCTL_SET_SBOX, gcry_cipher_set_sbox): New. * cipher/cipher.c (_gcry_cipher_ctl): pass GCRYCTL_SET_SBOX to set_extra_info callback. Signed-off-by: Dmitry Eremin-Solenikov diff --git a/NEWS b/NEWS index e1bb772..5eacf30 100644 --- a/NEWS +++ b/NEWS @@ -26,6 +26,8 @@ Noteworthy changes in version 1.7.0 (unreleased) gcry_mac_get_algo NEW. GCRY_MAC_HMAC_MD2 NEW. GCRY_MD_FLAG_BUGEMU1 NEW. + GCRYCTL_SET_SBOX NEW. + gcry_cipher_set_sbox NEW macro. Noteworthy changes in version 1.6.0 (2013-12-16) diff --git a/cipher/cipher.c b/cipher/cipher.c index da59061..5c44c0d 100644 --- a/cipher/cipher.c +++ b/cipher/cipher.c @@ -1264,6 +1264,13 @@ _gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen) } break; + case GCRYCTL_SET_SBOX: + if (h->spec->set_extra_info) + rc = h->spec->set_extra_info + (&h->context.c, GCRYCTL_SET_SBOX, buffer, buflen); + else + rc = GPG_ERR_NOT_SUPPORTED; + default: rc = GPG_ERR_INV_OP; } diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index bd38a24..95d324b 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -329,7 +329,8 @@ enum gcry_ctl_cmds GCRYCTL_SET_CCM_LENGTHS = 69, GCRYCTL_CLOSE_RANDOM_DEVICE = 70, GCRYCTL_INACTIVATE_FIPS_FLAG = 71, - GCRYCTL_REACTIVATE_FIPS_FLAG = 72 + GCRYCTL_REACTIVATE_FIPS_FLAG = 72, + GCRYCTL_SET_SBOX = 73 }; /* Perform various operations defined by CMD. */ @@ -1002,6 +1003,9 @@ gcry_error_t gcry_cipher_checktag (gcry_cipher_hd_t hd, const void *intag, #define gcry_cipher_cts(h,on) gcry_cipher_ctl( (h), GCRYCTL_SET_CBC_CTS, \ NULL, on ) +#define gcry_cipher_set_sbox(h,oid) gcry_cipher_ctl( (h), GCRYCTL_SET_SBOX, \ + (oid), 0); + /* Set counter for CTR mode. (CTR,CTRLEN) must denote a buffer of block size length, or (NULL,0) to set the CTR to the all-zero block. */ gpg_error_t gcry_cipher_setctr (gcry_cipher_hd_t hd, commit 164738a0292b3f32c7747099ad9cadace58e5eda Author: Dmitry Eremin-Solenikov Date: Fri Jun 6 22:48:29 2014 +0400 cipher/gost28147: generate optimized s-boxes from compact ones * cipher/gost-s-box.c: New. Outputs optimized expanded representation of s-boxes (4x256) from compact 16x8 representation. * cipher/Makefile.am: Add gost-sb.h dependency to gost28147.lo * cipher/gost.h: Add sbox to the GOST28147_context structure. * cipher/gost28147.c (gost_setkey): Set default s-box to test s-box from GOST R 34.11 (this was the only one S-box before). * cipher/gost28147.c (gost_val): Use sbox from the context. Signed-off-by: Dmitry Eremin-Solenikov diff --git a/.gitignore b/.gitignore index 8b235f9..3929e4d 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,8 @@ po/messages.mo /stamp-h1 /Makefile.in cipher/Makefile.in +cipher/gost-s-box +cipher/gost-sb.h compat/Makefile.in doc/Makefile.in m4/Makefile.in diff --git a/cipher/Makefile.am b/cipher/Makefile.am index 8a3bd19..c165356 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -93,6 +93,11 @@ rfc2268.c \ camellia.c camellia.h camellia-glue.c camellia-aesni-avx-amd64.S \ camellia-aesni-avx2-amd64.S camellia-arm.S +noinst_PROGRAMS = gost-s-box +gost28147.lo: gost-sb.h +gost-sb.h: gost-s-box + $(builddir)/gost-s-box $@ + if ENABLE_O_FLAG_MUNGING o_flag_munging = sed -e 's/-O\([2-9s][2-9s]*\)/-O1/' -e 's/-Ofast/-O1/g' else diff --git a/cipher/gost-s-box.c b/cipher/gost-s-box.c new file mode 100644 index 0000000..0094f65 --- /dev/null +++ b/cipher/gost-s-box.c @@ -0,0 +1,256 @@ +/* gost-s-box.c - GOST 28147-89 S-Box expander + * Copyright (C) 2013 Dmitry Eremin-Solenikov + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + */ + +#include +#include + +#define DIM(v) (sizeof(v)/sizeof((v)[0])) + +struct gost_sbox +{ + const char *name; + const char *oid; + unsigned char sbox[16*8]; +} gost_sboxes[] = { + { "test_3411", "1.2.643.2.2.30.0", { + 0x4, 0xE, 0x5, 0x7, 0x6, 0x4, 0xD, 0x1, + 0xA, 0xB, 0x8, 0xD, 0xC, 0xB, 0xB, 0xF, + 0x9, 0x4, 0x1, 0xA, 0x7, 0xA, 0x4, 0xD, + 0x2, 0xC, 0xD, 0x1, 0x1, 0x0, 0x1, 0x0, + + 0xD, 0x6, 0xA, 0x0, 0x5, 0x7, 0x3, 0x5, + 0x8, 0xD, 0x3, 0x8, 0xF, 0x2, 0xF, 0x7, + 0x0, 0xF, 0x4, 0x9, 0xD, 0x1, 0x5, 0xA, + 0xE, 0xA, 0x2, 0xF, 0x8, 0xD, 0x9, 0x4, + + 0x6, 0x2, 0xE, 0xE, 0x4, 0x3, 0x0, 0x9, + 0xB, 0x3, 0xF, 0x4, 0xA, 0x6, 0xA, 0x2, + 0x1, 0x8, 0xC, 0x6, 0x9, 0x8, 0xE, 0x3, + 0xC, 0x1, 0x7, 0xC, 0xE, 0x5, 0x7, 0xE, + + 0x7, 0x0, 0x6, 0xB, 0x0, 0x9, 0x6, 0x6, + 0xF, 0x7, 0x0, 0x2, 0x3, 0xC, 0x8, 0xB, + 0x5, 0x5, 0x9, 0x5, 0xB, 0xF, 0x2, 0x8, + 0x3, 0x9, 0xB, 0x3, 0x2, 0xE, 0xC, 0xC, + } + }, + { "CryptoPro_3411", "1.2.643.2.2.30.1", { + 0xA, 0x5, 0x7, 0x4, 0x7, 0x7, 0xD, 0x1, + 0x4, 0xF, 0xF, 0xA, 0x6, 0x6, 0xE, 0x3, + 0x5, 0x4, 0xC, 0x7, 0x4, 0x2, 0x4, 0xA, + 0x6, 0x0, 0xE, 0xC, 0xB, 0x4, 0x1, 0x9, + + 0x8, 0x2, 0x9, 0x0, 0x9, 0xD, 0x7, 0x5, + 0x1, 0xD, 0x4, 0xF, 0xC, 0x9, 0x0, 0xB, + 0x3, 0xB, 0x1, 0x2, 0x2, 0xF, 0x5, 0x4, + 0x7, 0x9, 0x0, 0x8, 0xA, 0x0, 0xA, 0xF, + + 0xD, 0x1, 0x3, 0xE, 0x1, 0xA, 0x3, 0x8, + 0xC, 0x7, 0xB, 0x1, 0x8, 0x1, 0xC, 0x6, + 0xE, 0x6, 0x5, 0x6, 0x0, 0x5, 0x8, 0x7, + 0x0, 0x3, 0x2, 0x5, 0xE, 0xB, 0xF, 0xE, + + 0x9, 0xC, 0x6, 0xD, 0xF, 0x8, 0x6, 0xD, + 0x2, 0xE, 0xA, 0xB, 0xD, 0xE, 0x2, 0x0, + 0xB, 0xA, 0x8, 0x9, 0x3, 0xC, 0x9, 0x2, + 0xF, 0x8, 0xD, 0x3, 0x5, 0x3, 0xB, 0xC, + } + }, + { "Test_89", "1.2.643.2.2.31.0", { + 0x4, 0xC, 0xD, 0xE, 0x3, 0x8, 0x9, 0xC, + 0x2, 0x9, 0x8, 0x9, 0xE, 0xF, 0xB, 0x6, + 0xF, 0xF, 0xE, 0xB, 0x5, 0x6, 0xC, 0x5, + 0x5, 0xE, 0xC, 0x2, 0x9, 0xB, 0x0, 0x2, + + 0x9, 0x8, 0x7, 0x5, 0x6, 0x1, 0x3, 0xB, + 0x1, 0x1, 0x3, 0xF, 0x8, 0x9, 0x6, 0x0, + 0x0, 0x3, 0x9, 0x7, 0x0, 0xC, 0x7, 0x9, + 0x8, 0xA, 0xA, 0x1, 0xD, 0x5, 0x5, 0xD, + + 0xE, 0x2, 0x1, 0x0, 0xA, 0xD, 0x4, 0x3, + 0x3, 0x7, 0x5, 0xD, 0xB, 0x3, 0x8, 0xE, + 0xB, 0x4, 0x2, 0xC, 0x7, 0x7, 0xE, 0x7, + 0xC, 0xD, 0x4, 0x6, 0xC, 0xA, 0xF, 0xA, + + 0xD, 0x6, 0x6, 0xA, 0x2, 0x0, 0x1, 0xF, + 0x7, 0x0, 0xF, 0x4, 0x1, 0xE, 0xA, 0x4, + 0xA, 0xB, 0x0, 0x3, 0xF, 0x2, 0x2, 0x1, + 0x6, 0x5, 0xB, 0x8, 0x4, 0x4, 0xD, 0x8, + } + }, + { "CryptoPro_A", "1.2.643.2.2.31.1", { + 0x9, 0x3, 0xE, 0xE, 0xB, 0x3, 0x1, 0xB, + 0x6, 0x7, 0x4, 0x7, 0x5, 0xA, 0xD, 0xA, + 0x3, 0xE, 0x6, 0xA, 0x1, 0xD, 0x2, 0xF, + 0x2, 0x9, 0x2, 0xC, 0x9, 0xC, 0x9, 0x5, + + 0x8, 0x8, 0xB, 0xD, 0x8, 0x1, 0x7, 0x0, + 0xB, 0xA, 0x3, 0x1, 0xD, 0x2, 0xA, 0xC, + 0x1, 0xF, 0xD, 0x3, 0xF, 0x0, 0x6, 0xE, + 0x7, 0x0, 0x8, 0x9, 0x0, 0xB, 0x0, 0x8, + + 0xA, 0x5, 0xC, 0x0, 0xE, 0x7, 0x8, 0x6, + 0x4, 0x2, 0xF, 0x2, 0x4, 0x5, 0xC, 0x2, + 0xE, 0x6, 0x5, 0xB, 0x2, 0x9, 0x4, 0x3, + 0xF, 0xC, 0xA, 0x4, 0x3, 0x4, 0x5, 0x9, + + 0xC, 0xB, 0x0, 0xF, 0xC, 0x8, 0xF, 0x1, + 0x0, 0x4, 0x7, 0x8, 0x7, 0xF, 0x3, 0x7, + 0xD, 0xD, 0x1, 0x5, 0xA, 0xE, 0xB, 0xD, + 0x5, 0x1, 0x9, 0x6, 0x6, 0x6, 0xE, 0x4, + } + }, + { "CryptoPro_B", "1.2.643.2.2.31.2", { + 0x8, 0x0, 0xE, 0x7, 0x2, 0x8, 0x5, 0x0, + 0x4, 0x1, 0xC, 0x5, 0x7, 0x3, 0x2, 0x4, + 0xB, 0x2, 0x0, 0x0, 0xC, 0x2, 0xA, 0xB, + 0x1, 0xA, 0xA, 0xD, 0xF, 0x6, 0xB, 0xE, + + 0x3, 0x4, 0x9, 0xB, 0x9, 0x4, 0x9, 0x8, + 0x5, 0xD, 0x2, 0x6, 0x5, 0xD, 0x1, 0x3, + 0x0, 0x5, 0xD, 0x1, 0xA, 0xE, 0xC, 0x7, + 0x9, 0xC, 0xB, 0x2, 0xB, 0xB, 0x3, 0x1, + + 0x2, 0x9, 0x7, 0x3, 0x1, 0xC, 0x7, 0xA, + 0xE, 0x7, 0x5, 0xA, 0x4, 0x1, 0x4, 0x2, + 0xA, 0x3, 0x8, 0xC, 0x0, 0x7, 0xD, 0x9, + 0xC, 0xF, 0xF, 0xF, 0xD, 0xF, 0x0, 0x6, + + 0x6, 0x8, 0x6, 0xE, 0x8, 0x0, 0xF, 0xD, + 0x7, 0x6, 0x1, 0x9, 0xE, 0x9, 0x8, 0x5, + 0xF, 0xE, 0x4, 0x8, 0x3, 0x5, 0xE, 0xC, + } + }, + { "CryptoPro_C", "1.2.643.2.2.31.3", { + 0x1, 0x0, 0x8, 0x3, 0x8, 0xC, 0xA, 0x7, + 0xB, 0x1, 0x2, 0x6, 0xD, 0x9, 0x9, 0x4, + 0xC, 0x7, 0x5, 0x0, 0xB, 0xB, 0x6, 0x0, + 0x2, 0xD, 0x0, 0x1, 0x0, 0x1, 0x8, 0x5, + + 0x9, 0xB, 0x4, 0x5, 0x4, 0x8, 0xD, 0xA, + 0xD, 0x4, 0x9, 0xD, 0x5, 0xE, 0xE, 0x2, + 0x0, 0x5, 0xF, 0xA, 0x1, 0x2, 0x2, 0xF, + 0xF, 0x2, 0xA, 0x8, 0x2, 0x4, 0x0, 0xE, + + 0x4, 0x8, 0x3, 0xB, 0x9, 0x7, 0xF, 0xC, + 0x5, 0xE, 0x7, 0x2, 0x3, 0x3, 0x3, 0x6, + 0x8, 0xF, 0xC, 0x9, 0xC, 0x6, 0x5, 0x1, + 0xE, 0xC, 0xD, 0x7, 0xE, 0x5, 0xB, 0xB, + + 0xA, 0x9, 0x6, 0xE, 0x6, 0xA, 0x4, 0xD, + 0x7, 0xA, 0xE, 0xF, 0xF, 0x0, 0x1, 0x9, + 0x6, 0x6, 0x1, 0xC, 0xA, 0xF, 0xC, 0x3, + 0x3, 0x3, 0xB, 0x4, 0x7, 0xD, 0x7, 0x8, + } + }, + { "CryptoPro_D", "1.2.643.2.2.31.4", { + 0xF, 0xB, 0x1, 0x1, 0x0, 0x8, 0x3, 0x1, + 0xC, 0x6, 0xC, 0x5, 0xC, 0x0, 0x0, 0xA, + 0x2, 0x3, 0xB, 0xE, 0x8, 0xF, 0x6, 0x6, + 0xA, 0x4, 0x0, 0xC, 0x9, 0x3, 0xF, 0x8, + + 0x6, 0xC, 0xF, 0xA, 0xD, 0x2, 0x1, 0xF, + 0x4, 0xF, 0xE, 0x7, 0x2, 0x5, 0xE, 0xB, + 0x5, 0xE, 0x6, 0x0, 0xA, 0xE, 0x9, 0x0, + 0x0, 0x2, 0x5, 0xD, 0xB, 0xB, 0x2, 0x4, + + 0x7, 0x7, 0xA, 0x6, 0x7, 0x1, 0xD, 0xC, + 0x9, 0xD, 0xD, 0x2, 0x3, 0xA, 0x8, 0x3, + 0xE, 0x8, 0x4, 0xB, 0x6, 0x4, 0xC, 0x5, + 0xD, 0x0, 0x8, 0x4, 0x5, 0x7, 0x4, 0x9, + + 0x1, 0x5, 0x9, 0x9, 0x4, 0xC, 0xB, 0x7, + 0xB, 0xA, 0x3, 0x3, 0xE, 0x9, 0xA, 0xD, + 0x8, 0x9, 0x7, 0xF, 0xF, 0xD, 0x5, 0x2, + 0x3, 0x1, 0x2, 0x8, 0x1, 0x6, 0x7, 0xE, + } + }, + { "TC26_A", "1.2.643.7.1.2.5.1.1", { + 0xc, 0x6, 0xb, 0xc, 0x7, 0x5, 0x8, 0x1, + 0x4, 0x8, 0x3, 0x8, 0xf, 0xd, 0xe, 0x7, + 0x6, 0x2, 0x5, 0x2, 0x5, 0xf, 0x2, 0xe, + 0x2, 0x3, 0x8, 0x1, 0xa, 0x6, 0x5, 0xd, + + 0xa, 0x9, 0x2, 0xd, 0x8, 0x9, 0x6, 0x0, + 0x5, 0xa, 0xf, 0x4, 0x1, 0x2, 0x9, 0x5, + 0xb, 0x5, 0xa, 0xf, 0x6, 0xc, 0x1, 0x8, + 0x9, 0xc, 0xd, 0x6, 0xd, 0xa, 0xc, 0x3, + + 0xe, 0x1, 0xe, 0x7, 0x0, 0xb, 0xf, 0x4, + 0x8, 0xe, 0x1, 0x0, 0x9, 0x7, 0x4, 0xf, + 0xd, 0x4, 0x7, 0xa, 0x3, 0x8, 0xb, 0xa, + 0x7, 0x7, 0x4, 0x5, 0xe, 0x1, 0x0, 0x6, + + 0x0, 0xb, 0xc, 0x3, 0xb, 0x4, 0xd, 0x9, + 0x3, 0xd, 0x9, 0xe, 0x4, 0x3, 0xa, 0xc, + 0xf, 0x0, 0x6, 0x9, 0x2, 0xe, 0x3, 0xb, + 0x1, 0xf, 0x0, 0xb, 0xc, 0x0, 0x7, 0x2, + } + }, +}; + +int main(int argc, char **argv) +{ + unsigned int i, j, s; + FILE *f; + + if (argc == 1) + f = stdin; + else + f = fopen(argv[1], "w"); + + if (!f) + { + perror("fopen"); + exit(1); + } + + for (s = 0; s < DIM(gost_sboxes); s++) + { + unsigned char *sbox = gost_sboxes[s].sbox; + fprintf (f, "static const u32 sbox_%s[4*256] =\n {", gost_sboxes[s].name); + for (i = 0; i < 4; i++) { + fprintf (f, "\n /* %d */\n ", i); + for (j = 0; j < 256; j++) { + unsigned int val; + if (j % 4 == 0 && j != 0) + fprintf (f, "\n "); + val = sbox[ (j & 0xf) * 8 + 2 * i + 0] | + (sbox[ (j >> 4) * 8 + 2 * i + 1] << 4); + val <<= (8*i); + val = (val << 11) | (val >> 21); + fprintf (f, " 0x%08x,", val); + } + } + fprintf (f, "\n };\n\n"); + } + + fprintf (f, "static struct\n{\n const char *oid;\n const u32 *sbox;\n} gost_oid_map[] = {\n"); + + for (s = 0; s < DIM(gost_sboxes); s++) + { + fprintf (f, " { \"%s\", sbox_%s },\n", gost_sboxes[s].oid, gost_sboxes[s].name ); + } + + fprintf(f, " { NULL, NULL }\n};\n"); + + fclose (f); + + return 0; +} diff --git a/cipher/gost.h b/cipher/gost.h index d058eb2..3fbd9df 100644 --- a/cipher/gost.h +++ b/cipher/gost.h @@ -22,6 +22,7 @@ typedef struct { u32 key[8]; + const u32 *sbox; } GOST28147_context; /* This is a simple interface that will be used by GOST R 34.11-94 */ diff --git a/cipher/gost28147.c b/cipher/gost28147.c index 1e48eb0..1720f45 100644 --- a/cipher/gost28147.c +++ b/cipher/gost28147.c @@ -34,277 +34,8 @@ #include "g10lib.h" #include "cipher.h" - -/* This is an s-box from RFC4357, named GostR3411-94-TestParamSet - * For now it is the only s-box supported, as libgcrypt lacks mechanism - * for passing parameters to cipher in a usefull way. - * S-boxes was modified from 4->4 to 8->8 bits unit with precalculated - * shift and rotation by optimisation reasons. - */ -static const u32 test_sbox[4][256] = { - /* 0 */ - { 0x00072000, 0x00075000, 0x00074800, 0x00071000, - 0x00076800, 0x00074000, 0x00070000, 0x00077000, - 0x00073000, 0x00075800, 0x00070800, 0x00076000, - 0x00073800, 0x00077800, 0x00072800, 0x00071800, - 0x0005a000, 0x0005d000, 0x0005c800, 0x00059000, - 0x0005e800, 0x0005c000, 0x00058000, 0x0005f000, - 0x0005b000, 0x0005d800, 0x00058800, 0x0005e000, - 0x0005b800, 0X0005F800, 0x0005a800, 0x00059800, - 0x00022000, 0x00025000, 0x00024800, 0x00021000, - 0x00026800, 0x00024000, 0x00020000, 0x00027000, - 0X00023000, 0x00025800, 0x00020800, 0x00026000, - 0x00023800, 0x00027800, 0x00022800, 0x00021800, - 0x00062000, 0x00065000, 0x00064800, 0x00061000, - 0x00066800, 0x00064000, 0x00060000, 0x00067000, - 0x00063000, 0x00065800, 0x00060800, 0x00066000, - 0x00063800, 0x00067800, 0x00062800, 0x00061800, - 0x00032000, 0x00035000, 0x00034800, 0x00031000, - 0x00036800, 0x00034000, 0x00030000, 0x00037000, - 0x00033000, 0x00035800, 0x00030800, 0x00036000, - 0x00033800, 0x00037800, 0x00032800, 0x00031800, - 0x0006a000, 0x0006d000, 0x0006c800, 0x00069000, - 0x0006e800, 0x0006c000, 0x00068000, 0x0006f000, - 0x0006b000, 0x0006d800, 0x00068800, 0x0006e000, - 0x0006b800, 0x0006f800, 0x0006a800, 0x00069800, - 0x0007a000, 0x0007d000, 0x0007c800, 0x00079000, - 0x0007e800, 0x0007c000, 0x00078000, 0x0007f000, - 0x0007b000, 0x0007d800, 0x00078800, 0x0007e000, - 0x0007b800, 0x0007f800, 0x0007a800, 0x00079800, - 0x00052000, 0x00055000, 0x00054800, 0x00051000, - 0x00056800, 0x00054000, 0x00050000, 0x00057000, - 0x00053000, 0x00055800, 0x00050800, 0x00056000, - 0x00053800, 0x00057800, 0x00052800, 0x00051800, - 0x00012000, 0x00015000, 0x00014800, 0x00011000, - 0x00016800, 0x00014000, 0x00010000, 0x00017000, - 0x00013000, 0x00015800, 0x00010800, 0x00016000, - 0x00013800, 0x00017800, 0x00012800, 0x00011800, - 0x0001a000, 0x0001d000, 0x0001c800, 0x00019000, - 0x0001e800, 0x0001c000, 0x00018000, 0x0001f000, - 0x0001b000, 0x0001d800, 0x00018800, 0x0001e000, - 0x0001b800, 0x0001f800, 0x0001a800, 0x00019800, - 0x00042000, 0x00045000, 0x00044800, 0x00041000, - 0x00046800, 0x00044000, 0x00040000, 0x00047000, - 0x00043000, 0x00045800, 0x00040800, 0x00046000, - 0x00043800, 0x00047800, 0x00042800, 0x00041800, - 0x0000a000, 0x0000d000, 0x0000c800, 0x00009000, - 0x0000e800, 0x0000c000, 0x00008000, 0x0000f000, - 0x0000b000, 0x0000d800, 0x00008800, 0x0000e000, - 0x0000b800, 0x0000f800, 0x0000a800, 0x00009800, - 0x00002000, 0x00005000, 0x00004800, 0x00001000, - 0x00006800, 0x00004000, 0x00000000, 0x00007000, - 0x00003000, 0x00005800, 0x00000800, 0x00006000, - 0x00003800, 0x00007800, 0x00002800, 0x00001800, - 0x0003a000, 0x0003d000, 0x0003c800, 0x00039000, - 0x0003e800, 0x0003c000, 0x00038000, 0x0003f000, - 0x0003b000, 0x0003d800, 0x00038800, 0x0003e000, - 0x0003b800, 0x0003f800, 0x0003a800, 0x00039800, - 0x0002a000, 0x0002d000, 0x0002c800, 0x00029000, - 0x0002e800, 0x0002c000, 0x00028000, 0x0002f000, - 0x0002b000, 0x0002d800, 0x00028800, 0x0002e000, - 0x0002b800, 0x0002f800, 0x0002a800, 0x00029800, - 0x0004a000, 0x0004d000, 0x0004c800, 0x00049000, - 0x0004e800, 0x0004c000, 0x00048000, 0x0004f000, - 0x0004b000, 0x0004d800, 0x00048800, 0x0004e000, - 0x0004b800, 0x0004f800, 0x0004a800, 0x00049800 }, - /* 1 */ - { 0x03a80000, 0x03c00000, 0x03880000, 0x03e80000, - 0x03d00000, 0x03980000, 0x03a00000, 0x03900000, - 0x03f00000, 0x03f80000, 0x03e00000, 0x03b80000, - 0x03b00000, 0x03800000, 0x03c80000, 0x03d80000, - 0x06a80000, 0x06c00000, 0x06880000, 0x06e80000, - 0x06d00000, 0x06980000, 0x06a00000, 0x06900000, - 0x06f00000, 0x06f80000, 0x06e00000, 0x06b80000, - 0x06b00000, 0x06800000, 0x06c80000, 0x06d80000, - 0x05280000, 0x05400000, 0x05080000, 0x05680000, - 0x05500000, 0x05180000, 0x05200000, 0x05100000, - 0x05700000, 0x05780000, 0x05600000, 0x05380000, - 0x05300000, 0x05000000, 0x05480000, 0x05580000, - 0x00a80000, 0x00c00000, 0x00880000, 0x00e80000, - 0x00d00000, 0x00980000, 0x00a00000, 0x00900000, - 0x00f00000, 0x00f80000, 0x00e00000, 0x00b80000, - 0x00b00000, 0x00800000, 0x00c80000, 0x00d80000, - 0x00280000, 0x00400000, 0x00080000, 0x00680000, - 0x00500000, 0x00180000, 0x00200000, 0x00100000, - 0x00700000, 0x00780000, 0x00600000, 0x00380000, - 0x00300000, 0x00000000, 0x00480000, 0x00580000, - 0x04280000, 0x04400000, 0x04080000, 0x04680000, - 0x04500000, 0x04180000, 0x04200000, 0x04100000, - 0x04700000, 0x04780000, 0x04600000, 0x04380000, - 0x04300000, 0x04000000, 0x04480000, 0x04580000, - 0x04a80000, 0x04c00000, 0x04880000, 0x04e80000, - 0x04d00000, 0x04980000, 0x04a00000, 0x04900000, - 0x04f00000, 0x04f80000, 0x04e00000, 0x04b80000, - 0x04b00000, 0x04800000, 0x04c80000, 0x04d80000, - 0x07a80000, 0x07c00000, 0x07880000, 0x07e80000, - 0x07d00000, 0x07980000, 0x07a00000, 0x07900000, - 0x07f00000, 0x07f80000, 0x07e00000, 0x07b80000, - 0x07b00000, 0x07800000, 0x07c80000, 0x07d80000, - 0x07280000, 0x07400000, 0x07080000, 0x07680000, - 0x07500000, 0x07180000, 0x07200000, 0x07100000, - 0x07700000, 0x07780000, 0x07600000, 0x07380000, - 0x07300000, 0x07000000, 0x07480000, 0x07580000, - 0x02280000, 0x02400000, 0x02080000, 0x02680000, - 0x02500000, 0x02180000, 0x02200000, 0x02100000, - 0x02700000, 0x02780000, 0x02600000, 0x02380000, - 0x02300000, 0x02000000, 0x02480000, 0x02580000, - 0x03280000, 0x03400000, 0x03080000, 0x03680000, - 0x03500000, 0x03180000, 0x03200000, 0x03100000, - 0x03700000, 0x03780000, 0x03600000, 0x03380000, - 0x03300000, 0x03000000, 0x03480000, 0x03580000, - 0x06280000, 0x06400000, 0x06080000, 0x06680000, - 0x06500000, 0x06180000, 0x06200000, 0x06100000, - 0x06700000, 0x06780000, 0x06600000, 0x06380000, - 0x06300000, 0x06000000, 0x06480000, 0x06580000, - 0x05a80000, 0x05c00000, 0x05880000, 0x05e80000, - 0x05d00000, 0x05980000, 0x05a00000, 0x05900000, - 0x05f00000, 0x05f80000, 0x05e00000, 0x05b80000, - 0x05b00000, 0x05800000, 0x05c80000, 0x05d80000, - 0x01280000, 0x01400000, 0x01080000, 0x01680000, - 0x01500000, 0x01180000, 0x01200000, 0x01100000, - 0x01700000, 0x01780000, 0x01600000, 0x01380000, - 0x01300000, 0x01000000, 0x01480000, 0x01580000, - 0x02a80000, 0x02c00000, 0x02880000, 0x02e80000, - 0x02d00000, 0x02980000, 0x02a00000, 0x02900000, - 0x02f00000, 0x02f80000, 0x02e00000, 0x02b80000, - 0x02b00000, 0x02800000, 0x02c80000, 0x02d80000, - 0x01a80000, 0x01c00000, 0x01880000, 0x01e80000, - 0x01d00000, 0x01980000, 0x01a00000, 0x01900000, - 0x01f00000, 0x01f80000, 0x01e00000, 0x01b80000, - 0x01b00000, 0x01800000, 0x01c80000, 0x01d80000 }, - /* 2 */ - { 0x30000002, 0x60000002, 0x38000002, 0x08000002, - 0x28000002, 0x78000002, 0x68000002, 0x40000002, - 0x20000002, 0x50000002, 0x48000002, 0x70000002, - 0x00000002, 0x18000002, 0x58000002, 0x10000002, - 0xb0000005, 0xe0000005, 0xb8000005, 0x88000005, - 0xa8000005, 0xf8000005, 0xe8000005, 0xc0000005, - 0xa0000005, 0xd0000005, 0xc8000005, 0xf0000005, - 0x80000005, 0x98000005, 0xd8000005, 0x90000005, - 0x30000005, 0x60000005, 0x38000005, 0x08000005, - 0x28000005, 0x78000005, 0x68000005, 0x40000005, - 0x20000005, 0x50000005, 0x48000005, 0x70000005, - 0x00000005, 0x18000005, 0x58000005, 0x10000005, - 0x30000000, 0x60000000, 0x38000000, 0x08000000, - 0x28000000, 0x78000000, 0x68000000, 0x40000000, - 0x20000000, 0x50000000, 0x48000000, 0x70000000, - 0x00000000, 0x18000000, 0x58000000, 0x10000000, - 0xb0000003, 0xe0000003, 0xb8000003, 0x88000003, - 0xa8000003, 0xf8000003, 0xe8000003, 0xc0000003, - 0xa0000003, 0xd0000003, 0xc8000003, 0xf0000003, - 0x80000003, 0x98000003, 0xd8000003, 0x90000003, - 0x30000001, 0x60000001, 0x38000001, 0x08000001, - 0x28000001, 0x78000001, 0x68000001, 0x40000001, - 0x20000001, 0x50000001, 0x48000001, 0x70000001, - 0x00000001, 0x18000001, 0x58000001, 0x10000001, - 0xb0000000, 0xe0000000, 0xb8000000, 0x88000000, - 0xa8000000, 0xf8000000, 0xe8000000, 0xc0000000, - 0xa0000000, 0xd0000000, 0xc8000000, 0xf0000000, - 0x80000000, 0x98000000, 0xd8000000, 0x90000000, - 0xb0000006, 0xe0000006, 0xb8000006, 0x88000006, - 0xa8000006, 0xf8000006, 0xe8000006, 0xc0000006, - 0xa0000006, 0xd0000006, 0xc8000006, 0xf0000006, - 0x80000006, 0x98000006, 0xd8000006, 0x90000006, - 0xb0000001, 0xe0000001, 0xb8000001, 0x88000001, - 0xa8000001, 0xf8000001, 0xe8000001, 0xc0000001, - 0xa0000001, 0xd0000001, 0xc8000001, 0xf0000001, - 0x80000001, 0x98000001, 0xd8000001, 0x90000001, - 0x30000003, 0x60000003, 0x38000003, 0x08000003, - 0x28000003, 0x78000003, 0x68000003, 0x40000003, - 0x20000003, 0x50000003, 0x48000003, 0x70000003, - 0x00000003, 0x18000003, 0x58000003, 0x10000003, - 0x30000004, 0x60000004, 0x38000004, 0x08000004, - 0x28000004, 0x78000004, 0x68000004, 0x40000004, - 0x20000004, 0x50000004, 0x48000004, 0x70000004, - 0x00000004, 0x18000004, 0x58000004, 0x10000004, - 0xb0000002, 0xe0000002, 0xb8000002, 0x88000002, - 0xa8000002, 0xf8000002, 0xe8000002, 0xc0000002, - 0xa0000002, 0xd0000002, 0xc8000002, 0xf0000002, - 0x80000002, 0x98000002, 0xd8000002, 0x90000002, - 0xb0000004, 0xe0000004, 0xb8000004, 0x88000004, - 0xa8000004, 0xf8000004, 0xe8000004, 0xc0000004, - 0xa0000004, 0xd0000004, 0xc8000004, 0xf0000004, - 0x80000004, 0x98000004, 0xd8000004, 0x90000004, - 0x30000006, 0x60000006, 0x38000006, 0x08000006, - 0x28000006, 0x78000006, 0x68000006, 0x40000006, - 0x20000006, 0x50000006, 0x48000006, 0x70000006, - 0x00000006, 0x18000006, 0x58000006, 0x10000006, - 0xb0000007, 0xe0000007, 0xb8000007, 0x88000007, - 0xa8000007, 0xf8000007, 0xe8000007, 0xc0000007, - 0xa0000007, 0xd0000007, 0xc8000007, 0xf0000007, - 0x80000007, 0x98000007, 0xd8000007, 0x90000007, - 0x30000007, 0x60000007, 0x38000007, 0x08000007, - 0x28000007, 0x78000007, 0x68000007, 0x40000007, - 0x20000007, 0x50000007, 0x48000007, 0x70000007, - 0x00000007, 0x18000007, 0x58000007, 0x10000007 }, - /* 3 */ - { 0x000000e8, 0x000000d8, 0x000000a0, 0x00000088, - 0x00000098, 0x000000f8, 0x000000a8, 0x000000c8, - 0x00000080, 0x000000d0, 0x000000f0, 0x000000b8, - 0x000000b0, 0x000000c0, 0x00000090, 0x000000e0, - 0x000007e8, 0x000007d8, 0x000007a0, 0x00000788, - 0x00000798, 0x000007f8, 0x000007a8, 0x000007c8, - 0x00000780, 0x000007d0, 0x000007f0, 0x000007b8, - 0x000007b0, 0x000007c0, 0x00000790, 0x000007e0, - 0x000006e8, 0x000006d8, 0x000006a0, 0x00000688, - 0x00000698, 0x000006f8, 0x000006a8, 0x000006c8, - 0x00000680, 0x000006d0, 0x000006f0, 0x000006b8, - 0x000006b0, 0x000006c0, 0x00000690, 0x000006e0, - 0x00000068, 0x00000058, 0x00000020, 0x00000008, - 0x00000018, 0x00000078, 0x00000028, 0x00000048, - 0x00000000, 0x00000050, 0x00000070, 0x00000038, - 0x00000030, 0x00000040, 0x00000010, 0x00000060, - 0x000002e8, 0x000002d8, 0x000002a0, 0x00000288, - 0x00000298, 0x000002f8, 0x000002a8, 0x000002c8, - 0x00000280, 0x000002d0, 0x000002f0, 0x000002b8, - 0x000002b0, 0x000002c0, 0x00000290, 0x000002e0, - 0x000003e8, 0x000003d8, 0x000003a0, 0x00000388, - 0x00000398, 0x000003f8, 0x000003a8, 0x000003c8, - 0x00000380, 0x000003d0, 0x000003f0, 0x000003b8, - 0x000003b0, 0x000003c0, 0x00000390, 0x000003e0, - 0x00000568, 0x00000558, 0x00000520, 0x00000508, - 0x00000518, 0x00000578, 0x00000528, 0x00000548, - 0x00000500, 0x00000550, 0x00000570, 0x00000538, - 0x00000530, 0x00000540, 0x00000510, 0x00000560, - 0x00000268, 0x00000258, 0x00000220, 0x00000208, - 0x00000218, 0x00000278, 0x00000228, 0x00000248, - 0x00000200, 0x00000250, 0x00000270, 0x00000238, - 0x00000230, 0x00000240, 0x00000210, 0x00000260, - 0x000004e8, 0x000004d8, 0x000004a0, 0x00000488, - 0x00000498, 0x000004f8, 0x000004a8, 0x000004c8, - 0x00000480, 0x000004d0, 0x000004f0, 0x000004b8, - 0x000004b0, 0x000004c0, 0x00000490, 0x000004e0, - 0x00000168, 0x00000158, 0x00000120, 0x00000108, - 0x00000118, 0x00000178, 0x00000128, 0x00000148, - 0x00000100, 0x00000150, 0x00000170, 0x00000138, - 0x00000130, 0x00000140, 0x00000110, 0x00000160, - 0x000001e8, 0x000001d8, 0x000001a0, 0x00000188, - 0x00000198, 0x000001f8, 0x000001a8, 0x000001c8, - 0x00000180, 0x000001d0, 0x000001f0, 0x000001b8, - 0x000001b0, 0x000001c0, 0x00000190, 0x000001e0, - 0x00000768, 0x00000758, 0x00000720, 0x00000708, - 0x00000718, 0x00000778, 0x00000728, 0x00000748, - 0x00000700, 0x00000750, 0x00000770, 0x00000738, - 0x00000730, 0x00000740, 0x00000710, 0x00000760, - 0x00000368, 0x00000358, 0x00000320, 0x00000308, - 0x00000318, 0x00000378, 0x00000328, 0x00000348, - 0x00000300, 0x00000350, 0x00000370, 0x00000338, - 0x00000330, 0x00000340, 0x00000310, 0x00000360, - 0x000005e8, 0x000005d8, 0x000005a0, 0x00000588, - 0x00000598, 0x000005f8, 0x000005a8, 0x000005c8, - 0x00000580, 0x000005d0, 0x000005f0, 0x000005b8, - 0x000005b0, 0x000005c0, 0x00000590, 0x000005e0, - 0x00000468, 0x00000458, 0x00000420, 0x00000408, - 0x00000418, 0x00000478, 0x00000428, 0x00000448, - 0x00000400, 0x00000450, 0x00000470, 0x00000438, - 0x00000430, 0x00000440, 0x00000410, 0x00000460, - 0x00000668, 0x00000658, 0x00000620, 0x00000608, - 0x00000618, 0x00000678, 0x00000628, 0x00000648, - 0x00000600, 0x00000650, 0x00000670, 0x00000638, - 0x00000630, 0x00000640, 0x00000610, 0x00000660 } -}; - #include "gost.h" +#include "gost-sb.h" static gcry_err_code_t gost_setkey (void *c, const byte *key, unsigned keylen) @@ -315,6 +46,9 @@ gost_setkey (void *c, const byte *key, unsigned keylen) if (keylen != 256 / 8) return GPG_ERR_INV_KEYLEN; + if (!ctx->sbox) + ctx->sbox = sbox_test_3411; + for (i = 0; i < 8; i++) { ctx->key[i] = (key[4 * i + 3] << 24) | @@ -329,10 +63,10 @@ static u32 gost_val (GOST28147_context *ctx, u32 cm1, int subkey) { cm1 += ctx->key[subkey]; - cm1 = test_sbox[0][ (cm1 >> 0) & 0xff] | - test_sbox[1][ (cm1 >> 8) & 0xff] | - test_sbox[2][ (cm1 >> 16) & 0xff] | - test_sbox[3][ (cm1 >> 24) & 0xff]; + cm1 = ctx->sbox[0*256 + ((cm1 >> 0) & 0xff)] | + ctx->sbox[1*256 + ((cm1 >> 8) & 0xff)] | + ctx->sbox[2*256 + ((cm1 >> 16) & 0xff)] | + ctx->sbox[3*256 + ((cm1 >> 24) & 0xff)]; return cm1; } commit 34a58010000288515636706811c3837f32957b2e Author: Dmitry Eremin-Solenikov Date: Fri Jun 6 22:48:28 2014 +0400 gost28147: add OIDs used to define cipher mode * cipher/gost28147 (oids_gost28147): Add OID from RFC4357. Signed-off-by: Dmitry Eremin-Solenikov diff --git a/cipher/gost28147.c b/cipher/gost28147.c index c094209..1e48eb0 100644 --- a/cipher/gost28147.c +++ b/cipher/gost28147.c @@ -441,10 +441,20 @@ gost_decrypt_block (void *c, byte *outbuf, const byte *inbuf) 4*sizeof(void*) /* gost_val call */; } +static gcry_cipher_oid_spec_t oids_gost28147[] = + { + /* { "1.2.643.2.2.31.0", GCRY_CIPHER_MODE_CNTGOST }, */ + { "1.2.643.2.2.31.1", GCRY_CIPHER_MODE_CFB }, + { "1.2.643.2.2.31.2", GCRY_CIPHER_MODE_CFB }, + { "1.2.643.2.2.31.3", GCRY_CIPHER_MODE_CFB }, + { "1.2.643.2.2.31.4", GCRY_CIPHER_MODE_CFB }, + { NULL } + }; + gcry_cipher_spec_t _gcry_cipher_spec_gost28147 = { GCRY_CIPHER_GOST28147, {0, 0}, - "GOST28147", NULL, NULL, 8, 256, + "GOST28147", NULL, oids_gost28147, 8, 256, sizeof (GOST28147_context), gost_setkey, gost_encrypt_block, commit 8b221cf5ce233c8c49a4e4ecebb70d523fc37837 Author: Dmitry Eremin-Solenikov Date: Fri Jun 6 22:48:26 2014 +0400 GOST R 34.11-94 add OIDs * cipher/gostr3411-94.c: Add OIDs for GOST R 34.11-94 from RFC 4357. Signed-off-by: Dmitry Eremin-Solenikov diff --git a/cipher/gostr3411-94.c b/cipher/gostr3411-94.c index 9a39733..73d570f 100644 --- a/cipher/gostr3411-94.c +++ b/cipher/gostr3411-94.c @@ -294,10 +294,23 @@ gost3411_read (void *context) return hd->h; } + +static unsigned char asn[6] = /* Object ID is 1.2.643.2.2.3 */ + { 0x2a, 0x85, 0x03, 0x02, 0x02, 0x03 }; + +static gcry_md_oid_spec_t oid_spec_gostr3411[] = + { + /* iso.member-body.ru.rans.cryptopro.3 (gostR3411-94-with-gostR3410-2001) */ + { "1.2.643.2.2.3" }, + /* iso.member-body.ru.rans.cryptopro.9 (gostR3411-94) */ + { "1.2.643.2.2.9" }, + {NULL}, + }; + gcry_md_spec_t _gcry_digest_spec_gost3411_94 = { GCRY_MD_GOSTR3411_94, {0, 0}, - "GOSTR3411_94", NULL, 0, NULL, 32, + "GOSTR3411_94", asn, DIM (asn), oid_spec_gostr3411, 32, gost3411_init, _gcry_md_block_write, gost3411_final, gost3411_read, sizeof (GOSTR3411_CONTEXT) }; ----------------------------------------------------------------------- Summary of changes: .gitignore | 2 + NEWS | 3 + cipher/Makefile.am | 5 + cipher/cipher.c | 7 + cipher/gost-s-box.c | 256 ++++++++++++++++++++++++++++++ cipher/gost.h | 5 +- cipher/gost28147.c | 411 +++++++++++-------------------------------------- cipher/gostr3411-94.c | 238 +++++++++++++++++----------- cipher/md.c | 2 + src/cipher.h | 1 + src/gcrypt.h.in | 9 +- tests/basic.c | 2 +- tests/t-kdf.c | 70 ++++++++- 13 files changed, 592 insertions(+), 419 deletions(-) create mode 100644 cipher/gost-s-box.c hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From jussi.kivilinna at iki.fi Sun Jun 29 13:18:35 2014 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Sun, 29 Jun 2014 14:18:35 +0300 Subject: [PATCH] Poly1305-AEAD: update to match latest Internet-Draft version In-Reply-To: <87mwd3k1ti.fsf@vigenere.g10code.de> References: <20140611164412.19049.99544.stgit@localhost6.localdomain6> <53A84F73.1020504@iki.fi> <87mwd3k1ti.fsf@vigenere.g10code.de> Message-ID: <53AFF60B.80004@iki.fi> On 23.06.2014 19:50, Werner Koch wrote: > On Mon, 23 Jun 2014 18:01, jussi.kivilinna at iki.fi said: > >> places, so it might be good idea to support both the old Poly1305-AEAD >> and the new. But what would be the best way to select between the two >> Poly1305-AEAD modes? > > We had the same probloem with the TIGER algorithm. Eventually we ended > up with 3 algorithm ids to support all variants and implementation bugs. > > Thus what about: > > GCRY_MAC_POLY1305X = 501, > GCRY_MAC_POLY1305X_AES = 502, > GCRY_MAC_POLY1305X_CAMELLIA = 503, > GCRY_MAC_POLY1305X_TWOFISH = 504, > GCRY_MAC_POLY1305X_SERPENT = 505, > GCRY_MAC_POLY1305X_SEED = 506, > GCRY_MAC_POLY1305 = 511, > GCRY_MAC_POLY1305_AES = 512, > GCRY_MAC_POLY1305_CAMELLIA = 513, > GCRY_MAC_POLY1305_TWOFISH = 514, > GCRY_MAC_POLY1305_SERPENT = 515, > GCRY_MAC_POLY1305_SEED = 516 > > or maybe better "OLD" instead of "X". Ok. Currently the MAC algorithm has not changed, so we'd be looking at cipher modes: GCRY_CIPHER_MODE_POLY1305OLD = 10, GCRY_CIPHER_MODE_POLY1305 = 11, /* or ..._POLY1305RFC */ Maybe it's better to wait for the actually RFC before adding new algorithm. -Jussi > > > Salam-Shalom, > > Werner > > From jussi.kivilinna at iki.fi Sun Jun 29 15:36:42 2014 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Sun, 29 Jun 2014 16:36:42 +0300 Subject: [PATCH] Speed-up SHA-1 NEON assembly implementation Message-ID: <20140629133642.6801.25223.stgit@localhost6.localdomain6> * cipher/sha1-armv7-neon.S: Tweak implementation for speed-up. -- Benchmark on Cortex-A8 1008Mhz: New: | nanosecs/byte mebibytes/sec cycles/byte SHA1 | 7.04 ns/B 135.4 MiB/s 7.10 c/B Old: | nanosecs/byte mebibytes/sec cycles/byte SHA1 | 7.79 ns/B 122.4 MiB/s 7.85 c/B Signed-off-by: Jussi Kivilinna --- cipher/sha1-armv7-neon.S | 155 ++++++++++++++++++++++++---------------------- 1 file changed, 82 insertions(+), 73 deletions(-) diff --git a/cipher/sha1-armv7-neon.S b/cipher/sha1-armv7-neon.S index 95b677d..f314d8e 100644 --- a/cipher/sha1-armv7-neon.S +++ b/cipher/sha1-armv7-neon.S @@ -1,5 +1,5 @@ /* sha1-armv7-neon.S - ARM/NEON accelerated SHA-1 transform function - * Copyright (C) 2013 Jussi Kivilinna + * Copyright (C) 2013-2014 Jussi Kivilinna * * Based on sha1.c: * Copyright (C) 1998, 2001, 2002, 2003, 2008 Free Software Foundation, Inc. @@ -26,12 +26,12 @@ defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) && \ defined(HAVE_GCC_INLINE_ASM_NEON) && defined(USE_SHA1) -.data - .syntax unified .fpu neon .arm +.text + #ifdef __PIC__ # define GET_DATA_POINTER(reg, name, rtmp) \ ldr reg, 1f; \ @@ -69,16 +69,13 @@ gcry_sha1_armv7_neon_K_VEC: .LK4: .long K4, K4, K4, K4 -.text - /* Register macros */ #define RSTATE r0 #define RDATA r1 #define RNBLKS r2 #define ROLDSTACK r3 -#define RK lr -#define RWK r12 +#define RWK lr #define _a r4 #define _b r5 @@ -89,6 +86,7 @@ gcry_sha1_armv7_neon_K_VEC: #define RT0 r9 #define RT1 r10 #define RT2 r11 +#define RT3 r12 #define W0 q0 #define W1 q1 @@ -104,7 +102,10 @@ gcry_sha1_armv7_neon_K_VEC: #define tmp2 q10 #define tmp3 q11 -#define curK q12 +#define qK1 q12 +#define qK2 q13 +#define qK3 q14 +#define qK4 q15 /* Round function macros. */ @@ -112,43 +113,43 @@ gcry_sha1_armv7_neon_K_VEC: #define WK_offs(i) (((i) & 15) * 4) #define _R_F1(a,b,c,d,e,i,pre1,pre2,pre3,i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \ - and RT0, c, b; \ + ldr RT3, [sp, WK_offs(i)]; \ pre1(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \ + bic RT0, d, b; \ add e, e, a, ror #(32 - 5); \ - ldr RT2, [sp, WK_offs(i)]; \ - bic RT1, d, b; \ - add e, RT2; \ + and RT1, c, b; \ pre2(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \ + add RT0, RT0, RT3; \ + add e, e, RT1; \ ror b, #(32 - 30); \ - eor RT0, RT1; \ pre3(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \ - add e, RT0; + add e, e, RT0; #define _R_F2(a,b,c,d,e,i,pre1,pre2,pre3,i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \ - eor RT0, c, b; \ + ldr RT3, [sp, WK_offs(i)]; \ pre1(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \ + eor RT0, d, b; \ add e, e, a, ror #(32 - 5); \ - ldr RT2, [sp, WK_offs(i)]; \ - eor RT0, d; \ + eor RT0, RT0, c; \ pre2(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \ - add e, RT2; \ + add e, e, RT3; \ ror b, #(32 - 30); \ pre3(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \ - add e, RT0; \ + add e, e, RT0; \ #define _R_F3(a,b,c,d,e,i,pre1,pre2,pre3,i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \ - eor RT0, c, b; \ + ldr RT3, [sp, WK_offs(i)]; \ pre1(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \ + eor RT0, b, c; \ + and RT1, b, c; \ add e, e, a, ror #(32 - 5); \ - ldr RT2, [sp, WK_offs(i)]; \ - and RT1, c, b; \ - and RT0, d; \ - add e, RT2; \ pre2(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \ + and RT0, RT0, d; \ + add RT1, RT1, RT3; \ + add e, e, RT0; \ ror b, #(32 - 30); \ - add e, RT1; \ pre3(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \ - add e, RT0; + add e, e, RT1; #define _R_F4(a,b,c,d,e,i,pre1,pre2,pre3,i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \ _R_F2(a,b,c,d,e,i,pre1,pre2,pre3,i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) @@ -183,10 +184,10 @@ gcry_sha1_armv7_neon_K_VEC: vst1.32 {tmp2, tmp3}, [RWK]; \ #define WPRECALC_00_15_0(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ - add RWK, sp, #(WK_offs(0)); \ + vld1.32 {tmp0, tmp1}, [RDATA]!; \ #define WPRECALC_00_15_1(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ - vld1.32 {tmp0, tmp1}, [RDATA]!; \ + add RWK, sp, #(WK_offs(0)); \ #define WPRECALC_00_15_2(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ vrev32.8 W0, tmp0; /* big => little */ \ @@ -225,25 +226,25 @@ gcry_sha1_armv7_neon_K_VEC: /********* Precalc macros for rounds 16-31 ************************************/ #define WPRECALC_16_31_0(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ - add RWK, sp, #(WK_offs(i)); \ - -#define WPRECALC_16_31_1(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ veor tmp0, tmp0; \ vext.8 W, W_m16, W_m12, #8; \ -#define WPRECALC_16_31_2(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ +#define WPRECALC_16_31_1(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ + add RWK, sp, #(WK_offs(i)); \ vext.8 tmp0, W_m04, tmp0, #4; \ + +#define WPRECALC_16_31_2(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ + veor tmp0, tmp0, W_m16; \ veor.32 W, W, W_m08; \ #define WPRECALC_16_31_3(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ - veor tmp0, tmp0, W_m16; \ veor tmp1, tmp1; \ + veor W, W, tmp0; \ #define WPRECALC_16_31_4(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ - veor W, W, tmp0; \ + vshl.u32 tmp0, W, #1; \ #define WPRECALC_16_31_5(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ - vshl.u32 tmp0, W, #1; \ vext.8 tmp1, tmp1, W, #(16-12); \ vshr.u32 W, W, #31; \ @@ -270,28 +271,28 @@ gcry_sha1_armv7_neon_K_VEC: /********* Precalc macros for rounds 32-79 ************************************/ #define WPRECALC_32_79_0(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ - add RWK, sp, #(WK_offs(i&~3)); \ + veor W, W_m28; \ #define WPRECALC_32_79_1(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ - veor W, W_m28; \ + vext.8 tmp0, W_m08, W_m04, #8; \ #define WPRECALC_32_79_2(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ - vext.8 tmp0, W_m08, W_m04, #8; \ + veor W, W_m16; \ #define WPRECALC_32_79_3(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ - veor W, W_m16; \ + veor W, tmp0; \ #define WPRECALC_32_79_4(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ - veor W, tmp0; \ + add RWK, sp, #(WK_offs(i&~3)); \ #define WPRECALC_32_79_5(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ - vshr.u32 tmp0, W, #30; \ + vshl.u32 tmp1, W, #2; \ #define WPRECALC_32_79_6(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ - vshl.u32 W, W, #2; \ + vshr.u32 tmp0, W, #30; \ #define WPRECALC_32_79_7(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ - vorr W, tmp0, W; \ + vorr W, tmp0, tmp1; \ #define WPRECALC_32_79_8(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ vadd.u32 tmp0, W, curK; \ @@ -326,20 +327,26 @@ _gcry_sha1_transform_armv7_neon: beq .Ldo_nothing; push {r4-r12, lr}; + + GET_DATA_POINTER(RT3, .LK_VEC, _a); vpush {q4-q7}; mov ROLDSTACK, sp; - GET_DATA_POINTER(RK, .LK_VEC, _a); /* Align stack. */ sub sp, #(16*4); and sp, #(~(16-1)); + vld1.32 {qK1-qK2}, [RT3]!; /* Load K1,K2 */ + /* Get the values of the chaining variables. */ ldm RSTATE, {_a-_e}; + vld1.32 {qK3-qK4}, [RT3]; /* Load K3,K4 */ + +#undef curK +#define curK qK1 /* Precalc 0-15. */ - vld1.32 {curK}, [RK]!; /* Load K1. */ W_PRECALC_00_15(); b .Loop; @@ -352,7 +359,8 @@ _gcry_sha1_transform_armv7_neon: _R( _d, _e, _a, _b, _c, F1, 2, WPRECALC_16_31_6, WPRECALC_16_31_7, WPRECALC_16_31_8, 16, W4, W5, W6, W7, W0, _, _, _ ); _R( _c, _d, _e, _a, _b, F1, 3, WPRECALC_16_31_9, WPRECALC_16_31_10,WPRECALC_16_31_11,16, W4, W5, W6, W7, W0, _, _, _ ); - vld1.32 {curK}, [RK]!; /* Load K2. */ +#undef curK +#define curK qK2 _R( _b, _c, _d, _e, _a, F1, 4, WPRECALC_16_31_0, WPRECALC_16_31_1, WPRECALC_16_31_2, 20, W3, W4, W5, W6, W7, _, _, _ ); _R( _a, _b, _c, _d, _e, F1, 5, WPRECALC_16_31_3, WPRECALC_16_31_4, WPRECALC_16_31_5, 20, W3, W4, W5, W6, W7, _, _, _ ); _R( _e, _a, _b, _c, _d, F1, 6, WPRECALC_16_31_6, WPRECALC_16_31_7, WPRECALC_16_31_8, 20, W3, W4, W5, W6, W7, _, _, _ ); @@ -371,72 +379,75 @@ _gcry_sha1_transform_armv7_neon: /* Transform 16-63 + Precalc 32-79. */ _R( _e, _a, _b, _c, _d, F1, 16, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 32, W0, W1, W2, W3, W4, W5, W6, W7); _R( _d, _e, _a, _b, _c, F1, 17, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 32, W0, W1, W2, W3, W4, W5, W6, W7); - _R( _c, _d, _e, _a, _b, F1, 18, WPRECALC_32_79_6, WPRECALC_32_79_7, dummy, 32, W0, W1, W2, W3, W4, W5, W6, W7); + _R( _c, _d, _e, _a, _b, F1, 18, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 32, W0, W1, W2, W3, W4, W5, W6, W7); _R( _b, _c, _d, _e, _a, F1, 19, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 32, W0, W1, W2, W3, W4, W5, W6, W7); _R( _a, _b, _c, _d, _e, F2, 20, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 36, W7, W0, W1, W2, W3, W4, W5, W6); _R( _e, _a, _b, _c, _d, F2, 21, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 36, W7, W0, W1, W2, W3, W4, W5, W6); - _R( _d, _e, _a, _b, _c, F2, 22, WPRECALC_32_79_6, WPRECALC_32_79_7, dummy, 36, W7, W0, W1, W2, W3, W4, W5, W6); + _R( _d, _e, _a, _b, _c, F2, 22, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 36, W7, W0, W1, W2, W3, W4, W5, W6); _R( _c, _d, _e, _a, _b, F2, 23, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 36, W7, W0, W1, W2, W3, W4, W5, W6); - vld1.32 {curK}, [RK]!; /* Load K3. */ +#undef curK +#define curK qK3 _R( _b, _c, _d, _e, _a, F2, 24, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 40, W6, W7, W0, W1, W2, W3, W4, W5); _R( _a, _b, _c, _d, _e, F2, 25, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 40, W6, W7, W0, W1, W2, W3, W4, W5); - _R( _e, _a, _b, _c, _d, F2, 26, WPRECALC_32_79_6, WPRECALC_32_79_7, dummy, 40, W6, W7, W0, W1, W2, W3, W4, W5); + _R( _e, _a, _b, _c, _d, F2, 26, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 40, W6, W7, W0, W1, W2, W3, W4, W5); _R( _d, _e, _a, _b, _c, F2, 27, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 40, W6, W7, W0, W1, W2, W3, W4, W5); _R( _c, _d, _e, _a, _b, F2, 28, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 44, W5, W6, W7, W0, W1, W2, W3, W4); _R( _b, _c, _d, _e, _a, F2, 29, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 44, W5, W6, W7, W0, W1, W2, W3, W4); - _R( _a, _b, _c, _d, _e, F2, 30, WPRECALC_32_79_6, WPRECALC_32_79_7, dummy, 44, W5, W6, W7, W0, W1, W2, W3, W4); + _R( _a, _b, _c, _d, _e, F2, 30, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 44, W5, W6, W7, W0, W1, W2, W3, W4); _R( _e, _a, _b, _c, _d, F2, 31, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 44, W5, W6, W7, W0, W1, W2, W3, W4); _R( _d, _e, _a, _b, _c, F2, 32, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 48, W4, W5, W6, W7, W0, W1, W2, W3); _R( _c, _d, _e, _a, _b, F2, 33, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 48, W4, W5, W6, W7, W0, W1, W2, W3); - _R( _b, _c, _d, _e, _a, F2, 34, WPRECALC_32_79_6, WPRECALC_32_79_7, dummy, 48, W4, W5, W6, W7, W0, W1, W2, W3); + _R( _b, _c, _d, _e, _a, F2, 34, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 48, W4, W5, W6, W7, W0, W1, W2, W3); _R( _a, _b, _c, _d, _e, F2, 35, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 48, W4, W5, W6, W7, W0, W1, W2, W3); _R( _e, _a, _b, _c, _d, F2, 36, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 52, W3, W4, W5, W6, W7, W0, W1, W2); _R( _d, _e, _a, _b, _c, F2, 37, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 52, W3, W4, W5, W6, W7, W0, W1, W2); - _R( _c, _d, _e, _a, _b, F2, 38, WPRECALC_32_79_6, WPRECALC_32_79_7, dummy, 52, W3, W4, W5, W6, W7, W0, W1, W2); + _R( _c, _d, _e, _a, _b, F2, 38, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 52, W3, W4, W5, W6, W7, W0, W1, W2); _R( _b, _c, _d, _e, _a, F2, 39, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 52, W3, W4, W5, W6, W7, W0, W1, W2); _R( _a, _b, _c, _d, _e, F3, 40, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 56, W2, W3, W4, W5, W6, W7, W0, W1); _R( _e, _a, _b, _c, _d, F3, 41, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 56, W2, W3, W4, W5, W6, W7, W0, W1); - _R( _d, _e, _a, _b, _c, F3, 42, WPRECALC_32_79_6, WPRECALC_32_79_7, dummy, 56, W2, W3, W4, W5, W6, W7, W0, W1); + _R( _d, _e, _a, _b, _c, F3, 42, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 56, W2, W3, W4, W5, W6, W7, W0, W1); _R( _c, _d, _e, _a, _b, F3, 43, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 56, W2, W3, W4, W5, W6, W7, W0, W1); - vld1.32 {curK}, [RK]!; /* Load K4. */ +#undef curK +#define curK qK4 _R( _b, _c, _d, _e, _a, F3, 44, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 60, W1, W2, W3, W4, W5, W6, W7, W0); _R( _a, _b, _c, _d, _e, F3, 45, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 60, W1, W2, W3, W4, W5, W6, W7, W0); - _R( _e, _a, _b, _c, _d, F3, 46, WPRECALC_32_79_6, WPRECALC_32_79_7, dummy, 60, W1, W2, W3, W4, W5, W6, W7, W0); + _R( _e, _a, _b, _c, _d, F3, 46, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 60, W1, W2, W3, W4, W5, W6, W7, W0); _R( _d, _e, _a, _b, _c, F3, 47, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 60, W1, W2, W3, W4, W5, W6, W7, W0); _R( _c, _d, _e, _a, _b, F3, 48, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 64, W0, W1, W2, W3, W4, W5, W6, W7); _R( _b, _c, _d, _e, _a, F3, 49, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 64, W0, W1, W2, W3, W4, W5, W6, W7); - _R( _a, _b, _c, _d, _e, F3, 50, WPRECALC_32_79_6, WPRECALC_32_79_7, dummy, 64, W0, W1, W2, W3, W4, W5, W6, W7); + _R( _a, _b, _c, _d, _e, F3, 50, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 64, W0, W1, W2, W3, W4, W5, W6, W7); _R( _e, _a, _b, _c, _d, F3, 51, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 64, W0, W1, W2, W3, W4, W5, W6, W7); _R( _d, _e, _a, _b, _c, F3, 52, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 68, W7, W0, W1, W2, W3, W4, W5, W6); _R( _c, _d, _e, _a, _b, F3, 53, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 68, W7, W0, W1, W2, W3, W4, W5, W6); - _R( _b, _c, _d, _e, _a, F3, 54, WPRECALC_32_79_6, WPRECALC_32_79_7, dummy, 68, W7, W0, W1, W2, W3, W4, W5, W6); + _R( _b, _c, _d, _e, _a, F3, 54, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 68, W7, W0, W1, W2, W3, W4, W5, W6); _R( _a, _b, _c, _d, _e, F3, 55, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 68, W7, W0, W1, W2, W3, W4, W5, W6); _R( _e, _a, _b, _c, _d, F3, 56, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 72, W6, W7, W0, W1, W2, W3, W4, W5); _R( _d, _e, _a, _b, _c, F3, 57, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 72, W6, W7, W0, W1, W2, W3, W4, W5); - _R( _c, _d, _e, _a, _b, F3, 58, WPRECALC_32_79_6, WPRECALC_32_79_7, dummy, 72, W6, W7, W0, W1, W2, W3, W4, W5); + _R( _c, _d, _e, _a, _b, F3, 58, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 72, W6, W7, W0, W1, W2, W3, W4, W5); _R( _b, _c, _d, _e, _a, F3, 59, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 72, W6, W7, W0, W1, W2, W3, W4, W5); - sub RK, #64; + subs RNBLKS, #1; + _R( _a, _b, _c, _d, _e, F4, 60, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 76, W5, W6, W7, W0, W1, W2, W3, W4); _R( _e, _a, _b, _c, _d, F4, 61, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 76, W5, W6, W7, W0, W1, W2, W3, W4); - _R( _d, _e, _a, _b, _c, F4, 62, WPRECALC_32_79_6, WPRECALC_32_79_7, dummy, 76, W5, W6, W7, W0, W1, W2, W3, W4); + _R( _d, _e, _a, _b, _c, F4, 62, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 76, W5, W6, W7, W0, W1, W2, W3, W4); _R( _c, _d, _e, _a, _b, F4, 63, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 76, W5, W6, W7, W0, W1, W2, W3, W4); - subs RNBLKS, #1; beq .Lend; /* Transform 64-79 + Precalc 0-15 of next block. */ - vld1.32 {curK}, [RK]!; /* Load K1. */ +#undef curK +#define curK qK1 _R( _b, _c, _d, _e, _a, F4, 64, WPRECALC_00_15_0, dummy, dummy, _, _, _, _, _, _, _, _, _ ); _R( _a, _b, _c, _d, _e, F4, 65, WPRECALC_00_15_1, dummy, dummy, _, _, _, _, _, _, _, _, _ ); _R( _e, _a, _b, _c, _d, F4, 66, WPRECALC_00_15_2, dummy, dummy, _, _, _, _, _, _, _, _, _ ); @@ -458,14 +469,13 @@ _gcry_sha1_transform_armv7_neon: _R( _b, _c, _d, _e, _a, F4, 79, WPRECALC_00_15_11, dummy, WPRECALC_00_15_12, _, _, _, _, _, _, _, _, _ ); /* Update the chaining variables. */ - ldm RSTATE, {RT0-RT2}; + ldm RSTATE, {RT0-RT3}; add _a, RT0; - ldr RT0, [RSTATE, #state_h3]; + ldr RT0, [RSTATE, #state_h4]; add _b, RT1; - ldr RT1, [RSTATE, #state_h4]; add _c, RT2; - add _d, RT0; - add _e, RT1; + add _d, RT3; + add _e, RT0; stm RSTATE, {_a-_e}; b .Loop; @@ -493,15 +503,14 @@ _gcry_sha1_transform_armv7_neon: mov sp, ROLDSTACK; /* Update the chaining variables. */ - ldm RSTATE, {RT0-RT2}; + ldm RSTATE, {RT0-RT3}; add _a, RT0; - ldr RT0, [RSTATE, #state_h3]; + ldr RT0, [RSTATE, #state_h4]; add _b, RT1; - ldr RT1, [RSTATE, #state_h4]; add _c, RT2; - add _d, RT0; + add _d, RT3; vpop {q4-q7}; - add _e, RT1; + add _e, RT0; stm RSTATE, {_a-_e}; /* burn_stack */ From cvs at cvs.gnupg.org Sun Jun 29 16:45:42 2014 From: cvs at cvs.gnupg.org (by Jussi Kivilinna) Date: Sun, 29 Jun 2014 16:45:42 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-94-g1b9b00b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 1b9b00bbe41bbed32563f1102049521e703e72bd (commit) from 066f068bd0bc4d8e01f1f18b6153cdc8d2c245d7 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1b9b00bbe41bbed32563f1102049521e703e72bd Author: Jussi Kivilinna Date: Sun Jun 29 17:36:29 2014 +0300 Speed-up SHA-1 NEON assembly implementation * cipher/sha1-armv7-neon.S: Tweak implementation for speed-up. -- Benchmark on Cortex-A8 1008Mhz: New: | nanosecs/byte mebibytes/sec cycles/byte SHA1 | 7.04 ns/B 135.4 MiB/s 7.10 c/B Old: | nanosecs/byte mebibytes/sec cycles/byte SHA1 | 7.79 ns/B 122.4 MiB/s 7.85 c/B Signed-off-by: Jussi Kivilinna diff --git a/cipher/sha1-armv7-neon.S b/cipher/sha1-armv7-neon.S index 95b677d..f314d8e 100644 --- a/cipher/sha1-armv7-neon.S +++ b/cipher/sha1-armv7-neon.S @@ -1,5 +1,5 @@ /* sha1-armv7-neon.S - ARM/NEON accelerated SHA-1 transform function - * Copyright (C) 2013 Jussi Kivilinna + * Copyright (C) 2013-2014 Jussi Kivilinna * * Based on sha1.c: * Copyright (C) 1998, 2001, 2002, 2003, 2008 Free Software Foundation, Inc. @@ -26,12 +26,12 @@ defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) && \ defined(HAVE_GCC_INLINE_ASM_NEON) && defined(USE_SHA1) -.data - .syntax unified .fpu neon .arm +.text + #ifdef __PIC__ # define GET_DATA_POINTER(reg, name, rtmp) \ ldr reg, 1f; \ @@ -69,16 +69,13 @@ gcry_sha1_armv7_neon_K_VEC: .LK4: .long K4, K4, K4, K4 -.text - /* Register macros */ #define RSTATE r0 #define RDATA r1 #define RNBLKS r2 #define ROLDSTACK r3 -#define RK lr -#define RWK r12 +#define RWK lr #define _a r4 #define _b r5 @@ -89,6 +86,7 @@ gcry_sha1_armv7_neon_K_VEC: #define RT0 r9 #define RT1 r10 #define RT2 r11 +#define RT3 r12 #define W0 q0 #define W1 q1 @@ -104,7 +102,10 @@ gcry_sha1_armv7_neon_K_VEC: #define tmp2 q10 #define tmp3 q11 -#define curK q12 +#define qK1 q12 +#define qK2 q13 +#define qK3 q14 +#define qK4 q15 /* Round function macros. */ @@ -112,43 +113,43 @@ gcry_sha1_armv7_neon_K_VEC: #define WK_offs(i) (((i) & 15) * 4) #define _R_F1(a,b,c,d,e,i,pre1,pre2,pre3,i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \ - and RT0, c, b; \ + ldr RT3, [sp, WK_offs(i)]; \ pre1(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \ + bic RT0, d, b; \ add e, e, a, ror #(32 - 5); \ - ldr RT2, [sp, WK_offs(i)]; \ - bic RT1, d, b; \ - add e, RT2; \ + and RT1, c, b; \ pre2(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \ + add RT0, RT0, RT3; \ + add e, e, RT1; \ ror b, #(32 - 30); \ - eor RT0, RT1; \ pre3(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \ - add e, RT0; + add e, e, RT0; #define _R_F2(a,b,c,d,e,i,pre1,pre2,pre3,i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \ - eor RT0, c, b; \ + ldr RT3, [sp, WK_offs(i)]; \ pre1(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \ + eor RT0, d, b; \ add e, e, a, ror #(32 - 5); \ - ldr RT2, [sp, WK_offs(i)]; \ - eor RT0, d; \ + eor RT0, RT0, c; \ pre2(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \ - add e, RT2; \ + add e, e, RT3; \ ror b, #(32 - 30); \ pre3(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \ - add e, RT0; \ + add e, e, RT0; \ #define _R_F3(a,b,c,d,e,i,pre1,pre2,pre3,i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \ - eor RT0, c, b; \ + ldr RT3, [sp, WK_offs(i)]; \ pre1(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \ + eor RT0, b, c; \ + and RT1, b, c; \ add e, e, a, ror #(32 - 5); \ - ldr RT2, [sp, WK_offs(i)]; \ - and RT1, c, b; \ - and RT0, d; \ - add e, RT2; \ pre2(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \ + and RT0, RT0, d; \ + add RT1, RT1, RT3; \ + add e, e, RT0; \ ror b, #(32 - 30); \ - add e, RT1; \ pre3(i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28); \ - add e, RT0; + add e, e, RT1; #define _R_F4(a,b,c,d,e,i,pre1,pre2,pre3,i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) \ _R_F2(a,b,c,d,e,i,pre1,pre2,pre3,i16,W,W_m04,W_m08,W_m12,W_m16,W_m20,W_m24,W_m28) @@ -183,10 +184,10 @@ gcry_sha1_armv7_neon_K_VEC: vst1.32 {tmp2, tmp3}, [RWK]; \ #define WPRECALC_00_15_0(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ - add RWK, sp, #(WK_offs(0)); \ + vld1.32 {tmp0, tmp1}, [RDATA]!; \ #define WPRECALC_00_15_1(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ - vld1.32 {tmp0, tmp1}, [RDATA]!; \ + add RWK, sp, #(WK_offs(0)); \ #define WPRECALC_00_15_2(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ vrev32.8 W0, tmp0; /* big => little */ \ @@ -225,25 +226,25 @@ gcry_sha1_armv7_neon_K_VEC: /********* Precalc macros for rounds 16-31 ************************************/ #define WPRECALC_16_31_0(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ - add RWK, sp, #(WK_offs(i)); \ - -#define WPRECALC_16_31_1(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ veor tmp0, tmp0; \ vext.8 W, W_m16, W_m12, #8; \ -#define WPRECALC_16_31_2(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ +#define WPRECALC_16_31_1(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ + add RWK, sp, #(WK_offs(i)); \ vext.8 tmp0, W_m04, tmp0, #4; \ + +#define WPRECALC_16_31_2(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ + veor tmp0, tmp0, W_m16; \ veor.32 W, W, W_m08; \ #define WPRECALC_16_31_3(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ - veor tmp0, tmp0, W_m16; \ veor tmp1, tmp1; \ + veor W, W, tmp0; \ #define WPRECALC_16_31_4(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ - veor W, W, tmp0; \ + vshl.u32 tmp0, W, #1; \ #define WPRECALC_16_31_5(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ - vshl.u32 tmp0, W, #1; \ vext.8 tmp1, tmp1, W, #(16-12); \ vshr.u32 W, W, #31; \ @@ -270,28 +271,28 @@ gcry_sha1_armv7_neon_K_VEC: /********* Precalc macros for rounds 32-79 ************************************/ #define WPRECALC_32_79_0(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ - add RWK, sp, #(WK_offs(i&~3)); \ + veor W, W_m28; \ #define WPRECALC_32_79_1(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ - veor W, W_m28; \ + vext.8 tmp0, W_m08, W_m04, #8; \ #define WPRECALC_32_79_2(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ - vext.8 tmp0, W_m08, W_m04, #8; \ + veor W, W_m16; \ #define WPRECALC_32_79_3(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ - veor W, W_m16; \ + veor W, tmp0; \ #define WPRECALC_32_79_4(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ - veor W, tmp0; \ + add RWK, sp, #(WK_offs(i&~3)); \ #define WPRECALC_32_79_5(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ - vshr.u32 tmp0, W, #30; \ + vshl.u32 tmp1, W, #2; \ #define WPRECALC_32_79_6(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ - vshl.u32 W, W, #2; \ + vshr.u32 tmp0, W, #30; \ #define WPRECALC_32_79_7(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ - vorr W, tmp0, W; \ + vorr W, tmp0, tmp1; \ #define WPRECALC_32_79_8(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28) \ vadd.u32 tmp0, W, curK; \ @@ -326,20 +327,26 @@ _gcry_sha1_transform_armv7_neon: beq .Ldo_nothing; push {r4-r12, lr}; + + GET_DATA_POINTER(RT3, .LK_VEC, _a); vpush {q4-q7}; mov ROLDSTACK, sp; - GET_DATA_POINTER(RK, .LK_VEC, _a); /* Align stack. */ sub sp, #(16*4); and sp, #(~(16-1)); + vld1.32 {qK1-qK2}, [RT3]!; /* Load K1,K2 */ + /* Get the values of the chaining variables. */ ldm RSTATE, {_a-_e}; + vld1.32 {qK3-qK4}, [RT3]; /* Load K3,K4 */ + +#undef curK +#define curK qK1 /* Precalc 0-15. */ - vld1.32 {curK}, [RK]!; /* Load K1. */ W_PRECALC_00_15(); b .Loop; @@ -352,7 +359,8 @@ _gcry_sha1_transform_armv7_neon: _R( _d, _e, _a, _b, _c, F1, 2, WPRECALC_16_31_6, WPRECALC_16_31_7, WPRECALC_16_31_8, 16, W4, W5, W6, W7, W0, _, _, _ ); _R( _c, _d, _e, _a, _b, F1, 3, WPRECALC_16_31_9, WPRECALC_16_31_10,WPRECALC_16_31_11,16, W4, W5, W6, W7, W0, _, _, _ ); - vld1.32 {curK}, [RK]!; /* Load K2. */ +#undef curK +#define curK qK2 _R( _b, _c, _d, _e, _a, F1, 4, WPRECALC_16_31_0, WPRECALC_16_31_1, WPRECALC_16_31_2, 20, W3, W4, W5, W6, W7, _, _, _ ); _R( _a, _b, _c, _d, _e, F1, 5, WPRECALC_16_31_3, WPRECALC_16_31_4, WPRECALC_16_31_5, 20, W3, W4, W5, W6, W7, _, _, _ ); _R( _e, _a, _b, _c, _d, F1, 6, WPRECALC_16_31_6, WPRECALC_16_31_7, WPRECALC_16_31_8, 20, W3, W4, W5, W6, W7, _, _, _ ); @@ -371,72 +379,75 @@ _gcry_sha1_transform_armv7_neon: /* Transform 16-63 + Precalc 32-79. */ _R( _e, _a, _b, _c, _d, F1, 16, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 32, W0, W1, W2, W3, W4, W5, W6, W7); _R( _d, _e, _a, _b, _c, F1, 17, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 32, W0, W1, W2, W3, W4, W5, W6, W7); - _R( _c, _d, _e, _a, _b, F1, 18, WPRECALC_32_79_6, WPRECALC_32_79_7, dummy, 32, W0, W1, W2, W3, W4, W5, W6, W7); + _R( _c, _d, _e, _a, _b, F1, 18, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 32, W0, W1, W2, W3, W4, W5, W6, W7); _R( _b, _c, _d, _e, _a, F1, 19, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 32, W0, W1, W2, W3, W4, W5, W6, W7); _R( _a, _b, _c, _d, _e, F2, 20, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 36, W7, W0, W1, W2, W3, W4, W5, W6); _R( _e, _a, _b, _c, _d, F2, 21, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 36, W7, W0, W1, W2, W3, W4, W5, W6); - _R( _d, _e, _a, _b, _c, F2, 22, WPRECALC_32_79_6, WPRECALC_32_79_7, dummy, 36, W7, W0, W1, W2, W3, W4, W5, W6); + _R( _d, _e, _a, _b, _c, F2, 22, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 36, W7, W0, W1, W2, W3, W4, W5, W6); _R( _c, _d, _e, _a, _b, F2, 23, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 36, W7, W0, W1, W2, W3, W4, W5, W6); - vld1.32 {curK}, [RK]!; /* Load K3. */ +#undef curK +#define curK qK3 _R( _b, _c, _d, _e, _a, F2, 24, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 40, W6, W7, W0, W1, W2, W3, W4, W5); _R( _a, _b, _c, _d, _e, F2, 25, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 40, W6, W7, W0, W1, W2, W3, W4, W5); - _R( _e, _a, _b, _c, _d, F2, 26, WPRECALC_32_79_6, WPRECALC_32_79_7, dummy, 40, W6, W7, W0, W1, W2, W3, W4, W5); + _R( _e, _a, _b, _c, _d, F2, 26, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 40, W6, W7, W0, W1, W2, W3, W4, W5); _R( _d, _e, _a, _b, _c, F2, 27, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 40, W6, W7, W0, W1, W2, W3, W4, W5); _R( _c, _d, _e, _a, _b, F2, 28, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 44, W5, W6, W7, W0, W1, W2, W3, W4); _R( _b, _c, _d, _e, _a, F2, 29, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 44, W5, W6, W7, W0, W1, W2, W3, W4); - _R( _a, _b, _c, _d, _e, F2, 30, WPRECALC_32_79_6, WPRECALC_32_79_7, dummy, 44, W5, W6, W7, W0, W1, W2, W3, W4); + _R( _a, _b, _c, _d, _e, F2, 30, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 44, W5, W6, W7, W0, W1, W2, W3, W4); _R( _e, _a, _b, _c, _d, F2, 31, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 44, W5, W6, W7, W0, W1, W2, W3, W4); _R( _d, _e, _a, _b, _c, F2, 32, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 48, W4, W5, W6, W7, W0, W1, W2, W3); _R( _c, _d, _e, _a, _b, F2, 33, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 48, W4, W5, W6, W7, W0, W1, W2, W3); - _R( _b, _c, _d, _e, _a, F2, 34, WPRECALC_32_79_6, WPRECALC_32_79_7, dummy, 48, W4, W5, W6, W7, W0, W1, W2, W3); + _R( _b, _c, _d, _e, _a, F2, 34, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 48, W4, W5, W6, W7, W0, W1, W2, W3); _R( _a, _b, _c, _d, _e, F2, 35, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 48, W4, W5, W6, W7, W0, W1, W2, W3); _R( _e, _a, _b, _c, _d, F2, 36, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 52, W3, W4, W5, W6, W7, W0, W1, W2); _R( _d, _e, _a, _b, _c, F2, 37, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 52, W3, W4, W5, W6, W7, W0, W1, W2); - _R( _c, _d, _e, _a, _b, F2, 38, WPRECALC_32_79_6, WPRECALC_32_79_7, dummy, 52, W3, W4, W5, W6, W7, W0, W1, W2); + _R( _c, _d, _e, _a, _b, F2, 38, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 52, W3, W4, W5, W6, W7, W0, W1, W2); _R( _b, _c, _d, _e, _a, F2, 39, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 52, W3, W4, W5, W6, W7, W0, W1, W2); _R( _a, _b, _c, _d, _e, F3, 40, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 56, W2, W3, W4, W5, W6, W7, W0, W1); _R( _e, _a, _b, _c, _d, F3, 41, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 56, W2, W3, W4, W5, W6, W7, W0, W1); - _R( _d, _e, _a, _b, _c, F3, 42, WPRECALC_32_79_6, WPRECALC_32_79_7, dummy, 56, W2, W3, W4, W5, W6, W7, W0, W1); + _R( _d, _e, _a, _b, _c, F3, 42, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 56, W2, W3, W4, W5, W6, W7, W0, W1); _R( _c, _d, _e, _a, _b, F3, 43, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 56, W2, W3, W4, W5, W6, W7, W0, W1); - vld1.32 {curK}, [RK]!; /* Load K4. */ +#undef curK +#define curK qK4 _R( _b, _c, _d, _e, _a, F3, 44, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 60, W1, W2, W3, W4, W5, W6, W7, W0); _R( _a, _b, _c, _d, _e, F3, 45, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 60, W1, W2, W3, W4, W5, W6, W7, W0); - _R( _e, _a, _b, _c, _d, F3, 46, WPRECALC_32_79_6, WPRECALC_32_79_7, dummy, 60, W1, W2, W3, W4, W5, W6, W7, W0); + _R( _e, _a, _b, _c, _d, F3, 46, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 60, W1, W2, W3, W4, W5, W6, W7, W0); _R( _d, _e, _a, _b, _c, F3, 47, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 60, W1, W2, W3, W4, W5, W6, W7, W0); _R( _c, _d, _e, _a, _b, F3, 48, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 64, W0, W1, W2, W3, W4, W5, W6, W7); _R( _b, _c, _d, _e, _a, F3, 49, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 64, W0, W1, W2, W3, W4, W5, W6, W7); - _R( _a, _b, _c, _d, _e, F3, 50, WPRECALC_32_79_6, WPRECALC_32_79_7, dummy, 64, W0, W1, W2, W3, W4, W5, W6, W7); + _R( _a, _b, _c, _d, _e, F3, 50, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 64, W0, W1, W2, W3, W4, W5, W6, W7); _R( _e, _a, _b, _c, _d, F3, 51, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 64, W0, W1, W2, W3, W4, W5, W6, W7); _R( _d, _e, _a, _b, _c, F3, 52, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 68, W7, W0, W1, W2, W3, W4, W5, W6); _R( _c, _d, _e, _a, _b, F3, 53, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 68, W7, W0, W1, W2, W3, W4, W5, W6); - _R( _b, _c, _d, _e, _a, F3, 54, WPRECALC_32_79_6, WPRECALC_32_79_7, dummy, 68, W7, W0, W1, W2, W3, W4, W5, W6); + _R( _b, _c, _d, _e, _a, F3, 54, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 68, W7, W0, W1, W2, W3, W4, W5, W6); _R( _a, _b, _c, _d, _e, F3, 55, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 68, W7, W0, W1, W2, W3, W4, W5, W6); _R( _e, _a, _b, _c, _d, F3, 56, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 72, W6, W7, W0, W1, W2, W3, W4, W5); _R( _d, _e, _a, _b, _c, F3, 57, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 72, W6, W7, W0, W1, W2, W3, W4, W5); - _R( _c, _d, _e, _a, _b, F3, 58, WPRECALC_32_79_6, WPRECALC_32_79_7, dummy, 72, W6, W7, W0, W1, W2, W3, W4, W5); + _R( _c, _d, _e, _a, _b, F3, 58, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 72, W6, W7, W0, W1, W2, W3, W4, W5); _R( _b, _c, _d, _e, _a, F3, 59, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 72, W6, W7, W0, W1, W2, W3, W4, W5); - sub RK, #64; + subs RNBLKS, #1; + _R( _a, _b, _c, _d, _e, F4, 60, WPRECALC_32_79_0, WPRECALC_32_79_1, WPRECALC_32_79_2, 76, W5, W6, W7, W0, W1, W2, W3, W4); _R( _e, _a, _b, _c, _d, F4, 61, WPRECALC_32_79_3, WPRECALC_32_79_4, WPRECALC_32_79_5, 76, W5, W6, W7, W0, W1, W2, W3, W4); - _R( _d, _e, _a, _b, _c, F4, 62, WPRECALC_32_79_6, WPRECALC_32_79_7, dummy, 76, W5, W6, W7, W0, W1, W2, W3, W4); + _R( _d, _e, _a, _b, _c, F4, 62, WPRECALC_32_79_6, dummy, WPRECALC_32_79_7, 76, W5, W6, W7, W0, W1, W2, W3, W4); _R( _c, _d, _e, _a, _b, F4, 63, WPRECALC_32_79_8, dummy, WPRECALC_32_79_9, 76, W5, W6, W7, W0, W1, W2, W3, W4); - subs RNBLKS, #1; beq .Lend; /* Transform 64-79 + Precalc 0-15 of next block. */ - vld1.32 {curK}, [RK]!; /* Load K1. */ +#undef curK +#define curK qK1 _R( _b, _c, _d, _e, _a, F4, 64, WPRECALC_00_15_0, dummy, dummy, _, _, _, _, _, _, _, _, _ ); _R( _a, _b, _c, _d, _e, F4, 65, WPRECALC_00_15_1, dummy, dummy, _, _, _, _, _, _, _, _, _ ); _R( _e, _a, _b, _c, _d, F4, 66, WPRECALC_00_15_2, dummy, dummy, _, _, _, _, _, _, _, _, _ ); @@ -458,14 +469,13 @@ _gcry_sha1_transform_armv7_neon: _R( _b, _c, _d, _e, _a, F4, 79, WPRECALC_00_15_11, dummy, WPRECALC_00_15_12, _, _, _, _, _, _, _, _, _ ); /* Update the chaining variables. */ - ldm RSTATE, {RT0-RT2}; + ldm RSTATE, {RT0-RT3}; add _a, RT0; - ldr RT0, [RSTATE, #state_h3]; + ldr RT0, [RSTATE, #state_h4]; add _b, RT1; - ldr RT1, [RSTATE, #state_h4]; add _c, RT2; - add _d, RT0; - add _e, RT1; + add _d, RT3; + add _e, RT0; stm RSTATE, {_a-_e}; b .Loop; @@ -493,15 +503,14 @@ _gcry_sha1_transform_armv7_neon: mov sp, ROLDSTACK; /* Update the chaining variables. */ - ldm RSTATE, {RT0-RT2}; + ldm RSTATE, {RT0-RT3}; add _a, RT0; - ldr RT0, [RSTATE, #state_h3]; + ldr RT0, [RSTATE, #state_h4]; add _b, RT1; - ldr RT1, [RSTATE, #state_h4]; add _c, RT2; - add _d, RT0; + add _d, RT3; vpop {q4-q7}; - add _e, RT1; + add _e, RT0; stm RSTATE, {_a-_e}; /* burn_stack */ ----------------------------------------------------------------------- Summary of changes: cipher/sha1-armv7-neon.S | 155 ++++++++++++++++++++++++---------------------- 1 file changed, 82 insertions(+), 73 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From wk at gnupg.org Sun Jun 29 21:50:49 2014 From: wk at gnupg.org (Werner Koch) Date: Sun, 29 Jun 2014 21:50:49 +0200 Subject: [PATCH] Poly1305-AEAD: update to match latest Internet-Draft version In-Reply-To: <53AFF60B.80004@iki.fi> (Jussi Kivilinna's message of "Sun, 29 Jun 2014 14:18:35 +0300") References: <20140611164412.19049.99544.stgit@localhost6.localdomain6> <53A84F73.1020504@iki.fi> <87mwd3k1ti.fsf@vigenere.g10code.de> <53AFF60B.80004@iki.fi> Message-ID: <874mz3a412.fsf@vigenere.g10code.de> On Sun, 29 Jun 2014 13:18, jussi.kivilinna at iki.fi said: > Maybe it's better to wait for the actually RFC before adding new algorithm. Definitely. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From dbaryshkov at gmail.com Mon Jun 30 02:04:27 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Mon, 30 Jun 2014 04:04:27 +0400 Subject: [PATCH 1/3] Stribog: change endianness of the final result Message-ID: <1404086669-11042-1-git-send-email-dbaryshkov@gmail.com> * cipher/stribog.c: change endianness of the hash result. * tests/basic.c (check_digests): adapt Stribog tests. -- Stribog standard (GOST R 34.11-2012) is a bit vague on the representation of the final result. This mistake is supported by GOST signatures being not so clear on the endianness of the hash value. Fix the Stribog result endianness to fully confirm to standard. This is proven by a (draft) publication of PBKDF2 test cases done by TC26. Signed-off-by: Dmitry Eremin-Solenikov --- cipher/stribog.c | 165 +++++++++++++++++++++++++------------------------------ tests/basic.c | 24 ++++---- 2 files changed, 86 insertions(+), 103 deletions(-) diff --git a/cipher/stribog.c b/cipher/stribog.c index 942bbf4..360cfec 100644 --- a/cipher/stribog.c +++ b/cipher/stribog.c @@ -1080,70 +1080,70 @@ static const u64 stribog_table[8][256] = U64_C(0x72d14d3493b2e388), U64_C(0xd6a30f258c153427) }, }; -static const u64 C16[13][16] = +static const u64 C16[12][8] = { - { U64_C(0xdd806559f2a64507), U64_C(0x05767436cc744d23), - U64_C(0xa2422a08a460d315), U64_C(0x4b7ce09192676901), - U64_C(0x714eb88d7585c4fc), U64_C(0x2f6a76432e45d016), - U64_C(0xebcb2f81c0657c1f), U64_C(0xb1085bda1ecadae9) }, - { U64_C(0xe679047021b19bb7), U64_C(0x55dda21bd7cbcd56), - U64_C(0x5cb561c2db0aa7ca), U64_C(0x9ab5176b12d69958), - U64_C(0x61d55e0f16b50131), U64_C(0xf3feea720a232b98), - U64_C(0x4fe39d460f70b5d7), U64_C(0x6fa3b58aa99d2f1a) }, - { U64_C(0x991e96f50aba0ab2), U64_C(0xc2b6f443867adb31), - U64_C(0xc1c93a376062db09), U64_C(0xd3e20fe490359eb1), - U64_C(0xf2ea7514b1297b7b), U64_C(0x06f15e5f529c1f8b), - U64_C(0x0a39fc286a3d8435), U64_C(0xf574dcac2bce2fc7) }, - { U64_C(0x220cbebc84e3d12e), U64_C(0x3453eaa193e837f1), - U64_C(0xd8b71333935203be), U64_C(0xa9d72c82ed03d675), - U64_C(0x9d721cad685e353f), U64_C(0x488e857e335c3c7d), - U64_C(0xf948e1a05d71e4dd), U64_C(0xef1fdfb3e81566d2) }, - { U64_C(0x601758fd7c6cfe57), U64_C(0x7a56a27ea9ea63f5), - U64_C(0xdfff00b723271a16), U64_C(0xbfcd1747253af5a3), - U64_C(0x359e35d7800fffbd), U64_C(0x7f151c1f1686104a), - U64_C(0x9a3f410c6ca92363), U64_C(0x4bea6bacad474799) }, - { U64_C(0xfa68407a46647d6e), U64_C(0xbf71c57236904f35), - U64_C(0x0af21f66c2bec6b6), U64_C(0xcffaa6b71c9ab7b4), - U64_C(0x187f9ab49af08ec6), U64_C(0x2d66c4f95142a46c), - U64_C(0x6fa4c33b7a3039c0), U64_C(0xae4faeae1d3ad3d9) }, - { U64_C(0x8886564d3a14d493), U64_C(0x3517454ca23c4af3), - U64_C(0x06476983284a0504), U64_C(0x0992abc52d822c37), - U64_C(0xd3473e33197a93c9), U64_C(0x399ec6c7e6bf87c9), - U64_C(0x51ac86febf240954), U64_C(0xf4c70e16eeaac5ec) }, - { U64_C(0xa47f0dd4bf02e71e), U64_C(0x36acc2355951a8d9), - U64_C(0x69d18d2bd1a5c42f), U64_C(0xf4892bcb929b0690), - U64_C(0x89b4443b4ddbc49a), U64_C(0x4eb7f8719c36de1e), - U64_C(0x03e7aa020c6e4141), U64_C(0x9b1f5b424d93c9a7) }, - { U64_C(0x7261445183235adb), U64_C(0x0e38dc92cb1f2a60), - U64_C(0x7b2b8a9aa6079c54), U64_C(0x800a440bdbb2ceb1), - U64_C(0x3cd955b7e00d0984), U64_C(0x3a7d3a1b25894224), - U64_C(0x944c9ad8ec165fde), U64_C(0x378f5a541631229b) }, - { U64_C(0x74b4c7fb98459ced), U64_C(0x3698fad1153bb6c3), - U64_C(0x7a1e6c303b7652f4), U64_C(0x9fe76702af69334b), - U64_C(0x1fffe18a1b336103), U64_C(0x8941e71cff8a78db), - U64_C(0x382ae548b2e4f3f3), U64_C(0xabbedea680056f52) }, - { U64_C(0x6bcaa4cd81f32d1b), U64_C(0xdea2594ac06fd85d), - U64_C(0xefbacd1d7d476e98), U64_C(0x8a1d71efea48b9ca), - U64_C(0x2001802114846679), U64_C(0xd8fa6bbbebab0761), - U64_C(0x3002c6cd635afe94), U64_C(0x7bcd9ed0efc889fb) }, - { U64_C(0x48bc924af11bd720), U64_C(0xfaf417d5d9b21b99), - U64_C(0xe71da4aa88e12852), U64_C(0x5d80ef9d1891cc86), - U64_C(0xf82012d430219f9b), U64_C(0xcda43c32bcdf1d77), - U64_C(0xd21380b00449b17a), U64_C(0x378ee767f11631ba) }, + { U64_C(0xb1085bda1ecadae9), U64_C(0xebcb2f81c0657c1f), + U64_C(0x2f6a76432e45d016), U64_C(0x714eb88d7585c4fc), + U64_C(0x4b7ce09192676901), U64_C(0xa2422a08a460d315), + U64_C(0x05767436cc744d23), U64_C(0xdd806559f2a64507) }, + { U64_C(0x6fa3b58aa99d2f1a), U64_C(0x4fe39d460f70b5d7), + U64_C(0xf3feea720a232b98), U64_C(0x61d55e0f16b50131), + U64_C(0x9ab5176b12d69958), U64_C(0x5cb561c2db0aa7ca), + U64_C(0x55dda21bd7cbcd56), U64_C(0xe679047021b19bb7) }, + { U64_C(0xf574dcac2bce2fc7), U64_C(0x0a39fc286a3d8435), + U64_C(0x06f15e5f529c1f8b), U64_C(0xf2ea7514b1297b7b), + U64_C(0xd3e20fe490359eb1), U64_C(0xc1c93a376062db09), + U64_C(0xc2b6f443867adb31), U64_C(0x991e96f50aba0ab2) }, + { U64_C(0xef1fdfb3e81566d2), U64_C(0xf948e1a05d71e4dd), + U64_C(0x488e857e335c3c7d), U64_C(0x9d721cad685e353f), + U64_C(0xa9d72c82ed03d675), U64_C(0xd8b71333935203be), + U64_C(0x3453eaa193e837f1), U64_C(0x220cbebc84e3d12e) }, + { U64_C(0x4bea6bacad474799), U64_C(0x9a3f410c6ca92363), + U64_C(0x7f151c1f1686104a), U64_C(0x359e35d7800fffbd), + U64_C(0xbfcd1747253af5a3), U64_C(0xdfff00b723271a16), + U64_C(0x7a56a27ea9ea63f5), U64_C(0x601758fd7c6cfe57) }, + { U64_C(0xae4faeae1d3ad3d9), U64_C(0x6fa4c33b7a3039c0), + U64_C(0x2d66c4f95142a46c), U64_C(0x187f9ab49af08ec6), + U64_C(0xcffaa6b71c9ab7b4), U64_C(0x0af21f66c2bec6b6), + U64_C(0xbf71c57236904f35), U64_C(0xfa68407a46647d6e) }, + { U64_C(0xf4c70e16eeaac5ec), U64_C(0x51ac86febf240954), + U64_C(0x399ec6c7e6bf87c9), U64_C(0xd3473e33197a93c9), + U64_C(0x0992abc52d822c37), U64_C(0x06476983284a0504), + U64_C(0x3517454ca23c4af3), U64_C(0x8886564d3a14d493) }, + { U64_C(0x9b1f5b424d93c9a7), U64_C(0x03e7aa020c6e4141), + U64_C(0x4eb7f8719c36de1e), U64_C(0x89b4443b4ddbc49a), + U64_C(0xf4892bcb929b0690), U64_C(0x69d18d2bd1a5c42f), + U64_C(0x36acc2355951a8d9), U64_C(0xa47f0dd4bf02e71e) }, + { U64_C(0x378f5a541631229b), U64_C(0x944c9ad8ec165fde), + U64_C(0x3a7d3a1b25894224), U64_C(0x3cd955b7e00d0984), + U64_C(0x800a440bdbb2ceb1), U64_C(0x7b2b8a9aa6079c54), + U64_C(0x0e38dc92cb1f2a60), U64_C(0x7261445183235adb) }, + { U64_C(0xabbedea680056f52), U64_C(0x382ae548b2e4f3f3), + U64_C(0x8941e71cff8a78db), U64_C(0x1fffe18a1b336103), + U64_C(0x9fe76702af69334b), U64_C(0x7a1e6c303b7652f4), + U64_C(0x3698fad1153bb6c3), U64_C(0x74b4c7fb98459ced) }, + { U64_C(0x7bcd9ed0efc889fb), U64_C(0x3002c6cd635afe94), + U64_C(0xd8fa6bbbebab0761), U64_C(0x2001802114846679), + U64_C(0x8a1d71efea48b9ca), U64_C(0xefbacd1d7d476e98), + U64_C(0xdea2594ac06fd85d), U64_C(0x6bcaa4cd81f32d1b) }, + { U64_C(0x378ee767f11631ba), U64_C(0xd21380b00449b17a), + U64_C(0xcda43c32bcdf1d77), U64_C(0xf82012d430219f9b), + U64_C(0x5d80ef9d1891cc86), U64_C(0xe71da4aa88e12852), + U64_C(0xfaf417d5d9b21b99), U64_C(0x48bc924af11bd720) }, }; #define strido(out, temp, i) do { \ u64 t; \ - t = stribog_table[0][(temp[0] >> (i * 8)) & 0xff]; \ - t ^= stribog_table[1][(temp[1] >> (i * 8)) & 0xff]; \ - t ^= stribog_table[2][(temp[2] >> (i * 8)) & 0xff]; \ - t ^= stribog_table[3][(temp[3] >> (i * 8)) & 0xff]; \ - t ^= stribog_table[4][(temp[4] >> (i * 8)) & 0xff]; \ - t ^= stribog_table[5][(temp[5] >> (i * 8)) & 0xff]; \ - t ^= stribog_table[6][(temp[6] >> (i * 8)) & 0xff]; \ - t ^= stribog_table[7][(temp[7] >> (i * 8)) & 0xff]; \ - out[i] = t; } while(0) + t = stribog_table[0][(temp[7] >> (i * 8)) & 0xff]; \ + t ^= stribog_table[1][(temp[6] >> (i * 8)) & 0xff]; \ + t ^= stribog_table[2][(temp[5] >> (i * 8)) & 0xff]; \ + t ^= stribog_table[3][(temp[4] >> (i * 8)) & 0xff]; \ + t ^= stribog_table[4][(temp[3] >> (i * 8)) & 0xff]; \ + t ^= stribog_table[5][(temp[2] >> (i * 8)) & 0xff]; \ + t ^= stribog_table[6][(temp[1] >> (i * 8)) & 0xff]; \ + t ^= stribog_table[7][(temp[0] >> (i * 8)) & 0xff]; \ + out[7-i] = t; } while(0) static void LPSX (u64 *out, const u64 *a, const u64 *b) { @@ -1227,14 +1227,14 @@ transform_bits (STRIBOG_CONTEXT *hd, const unsigned char *data, unsigned count) int i; for (i = 0; i < 8; i++) - M[i] = buf_get_le64(data + i * 8); + M[7-i] = buf_get_le64(data + i * 8); g (hd->h, M, hd->N); - l = hd->N[0]; - hd->N[0] += count; - if (hd->N[0] < l) + l = hd->N[7]; + hd->N[7] += count; + if (hd->N[7] < l) { /* overflow */ - for (i = 1; i < 8; i++) + for (i = 6; i >= 0; i++) { hd->N[i]++; if (hd->N[i] != 0) @@ -1242,22 +1242,12 @@ transform_bits (STRIBOG_CONTEXT *hd, const unsigned char *data, unsigned count) } } - hd->Sigma[0] += M[0]; - for (i = 1; i < 8; i++) - if (hd->Sigma[i-1] < M[i-1]) - hd->Sigma[i] += M[i] + 1; + hd->Sigma[7] += M[7]; + for (i = 7; i >= 1; i--) + if (hd->Sigma[i] < M[i]) + hd->Sigma[i-1] += M[i-1] + 1; else - hd->Sigma[i] += M[i]; -} - -static unsigned int -transform_blk (void *context, const unsigned char *inbuf_arg) -{ - STRIBOG_CONTEXT *hd = context; - - transform_bits (hd, inbuf_arg, 64 * 8); - - return /* burn_stack */ 768; + hd->Sigma[i-1] += M[i-1]; } static unsigned int @@ -1267,7 +1257,8 @@ transform ( void *c, const unsigned char *data, size_t nblks ) do { - burn = transform_blk (c, data); + transform_bits (c, data, 64 * 8); + burn = /* burn_stack */ 768; data += 64; } while (--nblks); @@ -1300,32 +1291,24 @@ stribog_final (void *context) g (hd->h, hd->Sigma, Z); for (i = 0; i < 8; i++) - hd->h[i] = le_bswap64(hd->h[i]); + hd->h[i] = be_bswap64(hd->h[i]); _gcry_burn_stack (768); } static byte * -stribog_read_512 (void *context) +stribog_read (void *context) { STRIBOG_CONTEXT *hd = context; return hd->result; } -static byte * -stribog_read_256 (void *context) -{ - STRIBOG_CONTEXT *hd = context; - - return hd->result + 32; -} - gcry_md_spec_t _gcry_digest_spec_stribog_256 = { GCRY_MD_STRIBOG256, {0, 0}, "STRIBOG256", NULL, 0, NULL, 32, - stribog_init_256, _gcry_md_block_write, stribog_final, stribog_read_256, + stribog_init_256, _gcry_md_block_write, stribog_final, stribog_read, sizeof (STRIBOG_CONTEXT) }; @@ -1333,6 +1316,6 @@ gcry_md_spec_t _gcry_digest_spec_stribog_512 = { GCRY_MD_STRIBOG512, {0, 0}, "STRIBOG512", NULL, 0, NULL, 64, - stribog_init_512, _gcry_md_block_write, stribog_final, stribog_read_512, + stribog_init_512, _gcry_md_block_write, stribog_final, stribog_read, sizeof (STRIBOG_CONTEXT) }; diff --git a/tests/basic.c b/tests/basic.c index 6d70cfd..f312fc0 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -4870,32 +4870,32 @@ check_digests (void) "\x8a\xcc\x14\x53\xb4\x87\xc8\x5c\x95\x9a\x3e\x85\x8c\x7d\x6e\x0c" }, { GCRY_MD_STRIBOG512, "012345678901234567890123456789012345678901234567890123456789012", - "\x1b\x54\xd0\x1a\x4a\xf5\xb9\xd5\xcc\x3d\x86\xd6\x8d\x28\x54\x62" - "\xb1\x9a\xbc\x24\x75\x22\x2f\x35\xc0\x85\x12\x2b\xe4\xba\x1f\xfa" - "\x00\xad\x30\xf8\x76\x7b\x3a\x82\x38\x4c\x65\x74\xf0\x24\xc3\x11" - "\xe2\xa4\x81\x33\x2b\x08\xef\x7f\x41\x79\x78\x91\xc1\x64\x6f\x48" }, + "\x48\x6f\x64\xc1\x91\x78\x79\x41\x7f\xef\x08\x2b\x33\x81\xa4\xe2" + "\x11\xc3\x24\xf0\x74\x65\x4c\x38\x82\x3a\x7b\x76\xf8\x30\xad\x00" + "\xfa\x1f\xba\xe4\x2b\x12\x85\xc0\x35\x2f\x22\x75\x24\xbc\x9a\xb1" + "\x62\x54\x28\x8d\xd6\x86\x3d\xcc\xd5\xb9\xf5\x4a\x1a\xd0\x54\x1b" }, { GCRY_MD_STRIBOG256, "012345678901234567890123456789012345678901234567890123456789012", - "\x9d\x15\x1e\xef\xd8\x59\x0b\x89\xda\xa6\xba\x6c\xb7\x4a\xf9\x27" - "\x5d\xd0\x51\x02\x6b\xb1\x49\xa4\x52\xfd\x84\xe5\xe5\x7b\x55\x00" }, + "\x00\x55\x7b\xe5\xe5\x84\xfd\x52\xa4\x49\xb1\x6b\x02\x51\xd0\x5d" + "\x27\xf9\x4a\xb7\x6c\xba\xa6\xda\x89\x0b\x59\xd8\xef\x1e\x15\x9d" }, { GCRY_MD_STRIBOG512, "\xd1\xe5\x20\xe2\xe5\xf2\xf0\xe8\x2c\x20\xd1\xf2\xf0\xe8\xe1\xee" "\xe6\xe8\x20\xe2\xed\xf3\xf6\xe8\x2c\x20\xe2\xe5\xfe\xf2\xfa\x20" "\xf1\x20\xec\xee\xf0\xff\x20\xf1\xf2\xf0\xe5\xeb\xe0\xec\xe8\x20" "\xed\xe0\x20\xf5\xf0\xe0\xe1\xf0\xfb\xff\x20\xef\xeb\xfa\xea\xfb" "\x20\xc8\xe3\xee\xf0\xe5\xe2\xfb", - "\x1e\x88\xe6\x22\x26\xbf\xca\x6f\x99\x94\xf1\xf2\xd5\x15\x69\xe0" - "\xda\xf8\x47\x5a\x3b\x0f\xe6\x1a\x53\x00\xee\xe4\x6d\x96\x13\x76" - "\x03\x5f\xe8\x35\x49\xad\xa2\xb8\x62\x0f\xcd\x7c\x49\x6c\xe5\xb3" - "\x3f\x0c\xb9\xdd\xdc\x2b\x64\x60\x14\x3b\x03\xda\xba\xc9\xfb\x28" }, + "\x28\xfb\xc9\xba\xda\x03\x3b\x14\x60\x64\x2b\xdc\xdd\xb9\x0c\x3f" + "\xb3\xe5\x6c\x49\x7c\xcd\x0f\x62\xb8\xa2\xad\x49\x35\xe8\x5f\x03" + "\x76\x13\x96\x6d\xe4\xee\x00\x53\x1a\xe6\x0f\x3b\x5a\x47\xf8\xda" + "\xe0\x69\x15\xd5\xf2\xf1\x94\x99\x6f\xca\xbf\x26\x22\xe6\x88\x1e" }, { GCRY_MD_STRIBOG256, "\xd1\xe5\x20\xe2\xe5\xf2\xf0\xe8\x2c\x20\xd1\xf2\xf0\xe8\xe1\xee" "\xe6\xe8\x20\xe2\xed\xf3\xf6\xe8\x2c\x20\xe2\xe5\xfe\xf2\xfa\x20" "\xf1\x20\xec\xee\xf0\xff\x20\xf1\xf2\xf0\xe5\xeb\xe0\xec\xe8\x20" "\xed\xe0\x20\xf5\xf0\xe0\xe1\xf0\xfb\xff\x20\xef\xeb\xfa\xea\xfb" "\x20\xc8\xe3\xee\xf0\xe5\xe2\xfb", - "\x9d\xd2\xfe\x4e\x90\x40\x9e\x5d\xa8\x7f\x53\x97\x6d\x74\x05\xb0" - "\xc0\xca\xc6\x28\xfc\x66\x9a\x74\x1d\x50\x06\x3c\x55\x7e\x8f\x50" }, + "\x50\x8f\x7e\x55\x3c\x06\x50\x1d\x74\x9a\x66\xfc\x28\xc6\xca\xc0" + "\xb0\x05\x74\x6d\x97\x53\x7f\xa8\x5d\x9e\x40\x90\x4e\xfe\xd2\x9d" }, { 0 } }; gcry_error_t err; -- 2.0.0 From dbaryshkov at gmail.com Mon Jun 30 02:04:28 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Mon, 30 Jun 2014 04:04:28 +0400 Subject: [PATCH 2/3] Add Stribog OIDs from TC26 space In-Reply-To: <1404086669-11042-1-git-send-email-dbaryshkov@gmail.com> References: <1404086669-11042-1-git-send-email-dbaryshkov@gmail.com> Message-ID: <1404086669-11042-2-git-send-email-dbaryshkov@gmail.com> Signed-off-by: Dmitry Eremin-Solenikov --- cipher/stribog.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/cipher/stribog.c b/cipher/stribog.c index 360cfec..fa16cfe 100644 --- a/cipher/stribog.c +++ b/cipher/stribog.c @@ -1304,10 +1304,24 @@ stribog_read (void *context) return hd->result; } +static gcry_md_oid_spec_t oid_spec_stribog256[] = + { + /* id-tc26-signwithdigest-gost3410-12-256 */ + { "1.2.643.7.1.1.3.2" }, + { NULL }, + }; + +static gcry_md_oid_spec_t oid_spec_stribog512[] = + { + /* id-tc26-signwithdigest-gost3410-12-512 */ + { "1.2.643.7.1.1.3.3" }, + { NULL }, + }; + gcry_md_spec_t _gcry_digest_spec_stribog_256 = { GCRY_MD_STRIBOG256, {0, 0}, - "STRIBOG256", NULL, 0, NULL, 32, + "STRIBOG256", NULL, 0, oid_spec_stribog256, 32, stribog_init_256, _gcry_md_block_write, stribog_final, stribog_read, sizeof (STRIBOG_CONTEXT) }; @@ -1315,7 +1329,7 @@ gcry_md_spec_t _gcry_digest_spec_stribog_256 = gcry_md_spec_t _gcry_digest_spec_stribog_512 = { GCRY_MD_STRIBOG512, {0, 0}, - "STRIBOG512", NULL, 0, NULL, 64, + "STRIBOG512", NULL, 0, oid_spec_stribog512, 64, stribog_init_512, _gcry_md_block_write, stribog_final, stribog_read, sizeof (STRIBOG_CONTEXT) }; -- 2.0.0 From dbaryshkov at gmail.com Mon Jun 30 02:04:29 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Mon, 30 Jun 2014 04:04:29 +0400 Subject: [PATCH 3/3] Add PBKDF2 tests for Stribog512 In-Reply-To: <1404086669-11042-1-git-send-email-dbaryshkov@gmail.com> References: <1404086669-11042-1-git-send-email-dbaryshkov@gmail.com> Message-ID: <1404086669-11042-3-git-send-email-dbaryshkov@gmail.com> * tests/t-kdf.c (check_pbkdf2): Add Stribog512 test cases. -- TC26 published a draft of PKCS#5 GOST extension containing test vectors for using Stribog512 in PBKDF2 scheme. Signed-off-by: Dmitry Eremin-Solenikov --- tests/t-kdf.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/tests/t-kdf.c b/tests/t-kdf.c index 8e728d5..f5610cf 100644 --- a/tests/t-kdf.c +++ b/tests/t-kdf.c @@ -989,11 +989,80 @@ check_pbkdf2 (void) 20, "\x43\xe0\x6c\x55\x90\xb0\x8c\x02\x25\x24" "\x23\x73\x12\x7e\xdf\x9c\x8e\x9c\x32\x91" + }, + { + "password", 8, + "salt", 4, + GCRY_MD_STRIBOG512, + 1, + 64, + "\xbc\xd1\x9a\x1c\x42\x3a\x63\xe7\x2e\x47\xef\x0f\x56\x56\x6c\x72" + "\x67\x45\xd9\x6a\xc1\xa1\xc1\x27\xb2\xed\xad\xb4\x5f\xb4\x5b\x30" + "\x7a\xca\x15\x99\x9e\x91\xf6\x40\xf4\x81\x8f\x68\xaf\x71\x6e\x30" + "\xfd\x54\x3c\x52\x02\x6b\xbb\x29\x5d\x10\x0e\xb4\x71\x33\x9f\x46" + }, + { + "password", 8, + "salt", 4, + GCRY_MD_STRIBOG512, + 2, + 64, + "\x08\x8f\xec\x3b\x0f\x1f\xfa\xf0\x61\x5e\xb2\x67\xde\x92\x90\x7f" + "\xd4\xe0\xbb\x89\xd2\xf5\xef\x9d\x41\x11\xa8\x0e\x3c\xbf\x23\x1a" + "\xf0\x7b\xa3\xce\x96\x06\x53\x95\xf8\xf1\xa7\x50\x5f\x97\x81\xf9" + "\x7e\x99\xa2\x6b\x83\x14\x90\x7d\xbf\x35\x10\xbc\x3c\xa2\x00\x0c" + }, + { + "password", 8, + "salt", 4, + GCRY_MD_STRIBOG512, + 4096, + 64, + "\x59\x6f\x63\x97\x1e\xae\x97\x0a\x4e\xac\x9c\x18\xbf\xf4\x2e\xc5" + "\x2b\x93\x6c\x1c\xca\xc6\xd1\x7c\xaa\x30\x8a\xfe\x12\xd4\xff\x31" + "\x94\x31\x80\xce\x02\xe4\x29\x56\x52\x4e\x99\x13\x92\xc4\xbd\xde" + "\xb7\x07\x7e\xdc\x1d\x2a\xbf\x52\xea\xf7\x2b\x9e\x32\xa8\xc6\x05" + }, + /* { -- takes toooo long + "password", 8, + "salt", 4, + GCRY_MD_STRIBOG512, + 16777216, + 64, + "\xeb\xf5\x12\xe4\xfe\x87\x51\x55\x21\x3d\x38\x81\x73\x8e\x10\x80" + "\x11\x6e\xfc\x12\xe0\x7e\xc6\x5c\xb7\x07\x20\x9d\x5e\xe8\x90\xd2" + "\x5b\xd4\xd9\x86\xca\xd5\xe1\x52\xaf\x23\x30\xf7\xfc\x29\x40\xeb" + "\x41\xf9\xbe\x0b\x1b\xae\xad\xfd\x43\x6e\xfb\x8c\x77\xd1\xc9\x13" + }, */ + { + "passwordPASSWORDpassword", 24, + "saltSALTsaltSALTsaltSALTsaltSALTsalt", 36, + GCRY_MD_STRIBOG512, + 4096, + 100, + "\xe4\x57\xee\x61\x26\xf0\x7c\x09\xbe\x00\x4b\xa5\x12\xad\xc9\x0c" + "\x61\x1c\x2b\x3f\xa1\x11\x41\xc2\x11\x96\xda\xe5\xa4\x8a\x50\xd8" + "\x3c\xcf\x16\x32\x33\xf0\x14\xfb\x6a\xde\x71\x69\x5b\xf3\x71\x59" + "\xe9\x06\x24\x43\xb7\x5d\xac\x91\x1f\xa7\xa1\x81\xd2\x4c\x4e\xd2" + "\xa9\x10\x49\x9d\x72\xab\xa9\x32\x84\xc7\x8d\xbc\x1a\xcb\xa2\x78" + "\x9b\xd8\xef\x50\xb5\x05\x2f\x33\xec\x6e\x24\x91\xf4\xf7\x4e\xda" + "\x05\x72\x38\x64" + }, + { + "pass\0word", 9, + "sa\0lt", 5, + GCRY_MD_STRIBOG512, + 4096, + 64, + "\xee\xd9\x2e\x8d\x76\xe1\x8d\x6a\x63\x2f\x2d\xa6\x5c\x9b\x28\x59" + "\xaf\x55\x5c\x33\x35\xea\x30\x09\x59\x89\xde\xa1\x4d\x9d\x09\x31" + "\x14\x66\x8e\x32\x9d\xeb\x03\x4c\xc1\x56\x5c\x3d\x73\x1d\xe0\xb5" + "\xca\x11\xac\xbd\xf8\x5a\xb9\xea\xab\x15\x29\x5d\xf0\x5b\x98\x05" } }; int tvidx; gpg_error_t err; - unsigned char outbuf[40]; + unsigned char outbuf[100]; int i; for (tvidx=0; tvidx < DIM(tv); tvidx++) -- 2.0.0 From wk at gnupg.org Mon Jun 30 06:48:29 2014 From: wk at gnupg.org (Werner Koch) Date: Mon, 30 Jun 2014 06:48:29 +0200 Subject: [PATCH 1/3] Stribog: change endianness of the final result In-Reply-To: <1404086669-11042-1-git-send-email-dbaryshkov@gmail.com> (Dmitry Eremin-Solenikov's message of "Mon, 30 Jun 2014 04:04:27 +0400") References: <1404086669-11042-1-git-send-email-dbaryshkov@gmail.com> Message-ID: <877g3z80ki.fsf@vigenere.g10code.de> On Mon, 30 Jun 2014 02:04, dbaryshkov at gmail.com said: > -static const u64 C16[13][16] = > +static const u64 C16[12][8] = Here you corrected an unrelated bug in the old code, right? Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From dbaryshkov at gmail.com Mon Jun 30 19:06:12 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Mon, 30 Jun 2014 21:06:12 +0400 Subject: [PATCH 1/3] Stribog: change endianness of the final result In-Reply-To: <877g3z80ki.fsf@vigenere.g10code.de> References: <1404086669-11042-1-git-send-email-dbaryshkov@gmail.com> <877g3z80ki.fsf@vigenere.g10code.de> Message-ID: On Mon, Jun 30, 2014 at 8:48 AM, Werner Koch wrote: > On Mon, 30 Jun 2014 02:04, dbaryshkov at gmail.com said: > >> -static const u64 C16[13][16] = >> +static const u64 C16[12][8] = > > Here you corrected an unrelated bug in the old code, right? Not quite a bug, but rather an overgrown array. -- With best wishes Dmitry