diff options
-rw-r--r-- | cipher/ChangeLog | 6 | ||||
-rw-r--r-- | cipher/Manifest | 24 | ||||
-rw-r--r-- | cipher/arcfour.c | 106 | ||||
-rw-r--r-- | cipher/blowfish.c | 446 | ||||
-rw-r--r-- | cipher/cast5.c | 63 | ||||
-rw-r--r-- | cipher/des.c | 388 | ||||
-rw-r--r-- | cipher/dsa.c | 459 | ||||
-rw-r--r-- | cipher/elgamal.c | 594 |
8 files changed, 1080 insertions, 1006 deletions
diff --git a/cipher/ChangeLog b/cipher/ChangeLog index e35bc76e..72e951e9 100644 --- a/cipher/ChangeLog +++ b/cipher/ChangeLog @@ -1,5 +1,11 @@ 2003-12-09 Werner Koch <wk@gnupg.org> + * dsa.c: Unified indentation style. + * elgamal.c: Ditto. + * des.c (des_key_schedule): Code beautifications. + * blowfish.c: Changed indentation style. + * cast5.c (do_cast_setkey): Ditto. + * pubkey.c (gcry_pk_encrypt): Replaced the chain of if(!err) tests by straightforward gotos. Other cleanups. (gcry_pk_decrypt): Ditto. diff --git a/cipher/Manifest b/cipher/Manifest index fb396633..7d8da6b3 100644 --- a/cipher/Manifest +++ b/cipher/Manifest @@ -28,25 +28,23 @@ # Algorithm API -cipher.c -pubkey.c -ac.c -md.c -primegen.c +cipher.c iQCVAwUAP9XQ7jEAnp832S/7AQLBiAQAjNHNCKQLQY3px/meGdYbLJ6U6E0jrbMV31XVPCetAp1FepTiRo4b8JcxZ50SsrMuSaG+nlp5Bf97jiNiOGl+iO1jssIWj3gOnWuBpqEAGyy9pmZLnBI0PS7oOQPHNnmP7W142a/dZrmaFZavGQ3IpUlVOULpZnUWWZm4UQCR+Y0==6m8b +pubkey.c iQCVAwUAP9XQ3jEAnp832S/7AQJ5UgQAyHfEBvPVJ8wTRg8c7ixS2GiVmIgwIo5tvQaiQJTPWASevvYrB+2Z2qa9cATyu50ACjLzbaquGBgPzjJV3dU/qttT1gCqRuN/LCNvXFe5qnIZezejc3RAadFNTw/pOTHq0wxD1Keg66ruei9R36Nba59pEQIWIBXTfubRft2hMYk==E09t # Algorithm implementations -arcfour.c -blowfish.c -cast5.c +arcfour.c iQCVAwUAP9XR/TEAnp832S/7AQJcRwP6AlvYEx++fpT4mIYo0xRDqKEQeqMQvbaRhIg2eV74JxItpHa3q5YsYIl+n1yUz5g35JRWWXSWmAZBwO5wLKsHii4kRUhgrKWnSoQZoPpl49L5+N3R58ON3S0ru5lsBiEJEze3xplf2vqwrH9v1QHVD+gU7UTlfNqrIJoOUXN+1O4==Tq+x +blowfish.c iQCVAwUAP9XTETEAnp832S/7AQJaEgQAgiqqfuO+zQtscgTB0rvOzVymIKjRKjYhFuLjVuc79G4z1RCAffvIn/YM2d7kt+Z/QF7zjcTAOgETCQL1XokpX2zz9HPAMi2tlDY5zsDufTNqj0n4WBL9nM7w6XAvsiwP1B3bqCTv9SjJV4KbxJ58vw1yQE+sqW74R/QIHFvC7mU==wZnX +cast5.c iQCVAwUAP9XT6DEAnp832S/7AQJ3xgP/ehLjEN3GELGudbqeo91Xd+PqitHrkuBbtRIYX7Udd/fyXLN+h8rMJVyIQX2m+mpxbBxudVU3x8/DNT8B0ZHAwK6qqJmEBLLhEYPgIuF76i9LMrP1KqUPhAwRZ2OppjIIugBQ+rP74aD4eLyd/aKQHNuXML8QGWR6KwQShohXM5I==/BRh crc.c iQCVAwUAP7ouejEAnp832S/7AQIgwQQApg5Nm63tH5DQkbN+zPzMO9Ygoj3ukxfFTyTBPYSXYKMiTjEbESegaU40uN8jnz2vprcIQWcgZfzO4+opEJMcI35aPwzEk0vKOp0S/PrBLUY2rJfnDVkX5XgJFZa2Q7LLe826UEBzTVYW924utiCCe8oOaOEWVNpg1mqdknu3M9o==kz5D -des.c -dsa.c -elgamal.c +des.c iQCVAwUAP9XWVDEAnp832S/7AQLjYgP8DTVwIS1L/eODK2HOCuJgIqAg1MS9Jpb1w56pKM4pOQ24mH/pMWUgksntW1PqGXRzqt66k+AFw200/AujbEcEmB4kTmMRVYIDUrextWXsg8AQUaUqxPD6pP0mq2Y6afhCgaRm0rAYDz2kI2RRRxHPyRhwi/j+TNke01AdnnK1k2A==xGcy +dsa.c iQCVAwUAP9XZHDEAnp832S/7AQLBRgP/XrBzTEYx5ccMj1MMb6sg37liEHdIyyy49zjvt6jUqxj4RuwVEN8S6v3u4q/QyJkHAi1E0EkREgENlyHW6PKWhYbcrd0vPIAN15yjnl2yqtrCrJImexUCoqJJewK0E4JOicGbabTil8MZjk+mbhEPnjJBqOkyP1w0i31pEDgE/8M==pC8s +elgamal.c iQCVAwUAP9XbYzEAnp832S/7AQLXagQA3HrvspZfbTGgmUH0IqLQTJ0exUPxJv5DET2TvoIy62trDmMN6lTAj5P+a7jQ8udcu0w+mR2vXUHcxUpNA2PxLaMwGzNSY4zRDNe9r3SFTDrFm6m4y9Ko2e8XtEA+WF6P/XLpck4Jn7vMEDmVGPwkNd22kXFFE8dBGwG6i5Hk1Mk==oBUs md4.c md5.c rijndael.c rmd160.c -rsa.c serpent.c +rsa.c +serpent.c sha1.c sha256.c sha512.c @@ -68,4 +66,4 @@ rmd.h iQCVAwUAP7oumjEAnp832S/7AQJiJQP/V4bJwjZaYndJzV+KRnIDbl1koHuw+ZK5heMYVu8Qk4 # Configuration Makefile.am iQCVAwUAP7otvTEAnp832S/7AQJSRAQA22xFVzkSrsO7aoWxgJaJwDyHD6FC41au6+NGc1EpY/phUGtzmV/lvGuTz/VVe0hKP9UmUmIs8vVUf6UlrR26ePFwsk5ziForI4b8F18nIZQmt2TJNMIEN6N8rRPMmZCFEnWyT2z3+2kNrDUjanqY7mcKkT7ywB7qwwFeQ7egr3k==3zw5 -$names$ iQCVAwUAP7oq4DEAnp832S/7AQLJ9gQAwNn8FjvvH+7cKIfvgki+wS81lOe+tXdRBKgPwHteQy8N/VrusLtasqB6JmAX4RDL/3Y0IsX9lkuZS2S1XPB+JnjT6F2zt+jVmGgY6nDLMZUlZI++5Mz0s5qDiAGUC0vIA7dvICWNjDjFVEsKjcMlWRw16plTF2fe/yUjwsCGG1s==G7kF +$names$ iQCVAwUAP9XbjTEAnp832S/7AQIBewQAnvyDvWAo2r1G/g4J1QGU3ERkDuxbxNbaUnMsTcmGs+Muhql5M59dv1SRUF9IqDSTuYkTIh8K76rhM+937iINYUgHxrgHBrrAOJ/HYIgCiBp7fwJfi8z/4WS1BZqlCknkmf1oI8tc1ynAhQM2UM4LjMLS619F2SFKRvSQZ8u3Z1g==C1b0 diff --git a/cipher/arcfour.c b/cipher/arcfour.c index c41ff0d5..6bb0555c 100644 --- a/cipher/arcfour.c +++ b/cipher/arcfour.c @@ -50,7 +50,7 @@ do_encrypt_stream( ARCFOUR_context *ctx, while ( length-- ) { i++; - i = i & 255; /* and seems to be faster than mod */ + i = i & 255; /* The and-op seems to be faster than the mod-op. */ j += sbox[i]; j &= 255; t = sbox[i]; sbox[i] = sbox[j]; sbox[j] = t; @@ -74,39 +74,41 @@ encrypt_stream (void *context, static gcry_err_code_t do_arcfour_setkey (void *context, const byte *key, unsigned int keylen) { - static int initialized; - static const char* selftest_failed; - int i, j; - byte karr[256]; - ARCFOUR_context *ctx = (ARCFOUR_context *) context; - - if( !initialized ) { - initialized = 1; - selftest_failed = selftest(); - if( selftest_failed ) - log_error ("ARCFOUR selftest failed (%s)\n", selftest_failed ); + static int initialized; + static const char* selftest_failed; + int i, j; + byte karr[256]; + ARCFOUR_context *ctx = (ARCFOUR_context *) context; + + if (!initialized ) + { + initialized = 1; + selftest_failed = selftest(); + if( selftest_failed ) + log_error ("ARCFOUR selftest failed (%s)\n", selftest_failed ); } - if( selftest_failed ) - return GPG_ERR_SELFTEST_FAILED; - - if( keylen < 40/8 ) /* we want at least 40 bits */ - return GPG_ERR_INV_KEYLEN; - - ctx->idx_i = ctx->idx_j = 0; - for (i=0; i < 256; i++ ) - ctx->sbox[i] = i; - for (i=0; i < 256; i++ ) - karr[i] = key[i%keylen]; - for (i=j=0; i < 256; i++ ) { - int t; - j = (j + ctx->sbox[i] + karr[i]) % 256; - t = ctx->sbox[i]; - ctx->sbox[i] = ctx->sbox[j]; - ctx->sbox[j] = t; + if( selftest_failed ) + return GPG_ERR_SELFTEST_FAILED; + + if( keylen < 40/8 ) /* we want at least 40 bits */ + return GPG_ERR_INV_KEYLEN; + + ctx->idx_i = ctx->idx_j = 0; + for (i=0; i < 256; i++ ) + ctx->sbox[i] = i; + for (i=0; i < 256; i++ ) + karr[i] = key[i%keylen]; + for (i=j=0; i < 256; i++ ) + { + int t; + j = (j + ctx->sbox[i] + karr[i]) % 256; + t = ctx->sbox[i]; + ctx->sbox[i] = ctx->sbox[j]; + ctx->sbox[j] = t; } - memset( karr, 0, 256 ); + memset( karr, 0, 256 ); - return GPG_ERR_NO_ERROR; + return GPG_ERR_NO_ERROR; } static gcry_err_code_t @@ -122,33 +124,33 @@ arcfour_setkey ( void *context, const byte *key, unsigned int keylen ) static const char* selftest(void) { - ARCFOUR_context ctx; - byte scratch[16]; + ARCFOUR_context ctx; + byte scratch[16]; - /* Test vector from Cryptlib labeled there: - * "from the State/Commerce Department" */ - static byte key_1[] = - { 0x61, 0x8A, 0x63, 0xD2, 0xFB }; - static byte plaintext_1[] = - { 0xDC, 0xEE, 0x4C, 0xF9, 0x2C }; - static const byte ciphertext_1[] = - { 0xF1, 0x38, 0x29, 0xC9, 0xDE }; - - arcfour_setkey( &ctx, key_1, sizeof(key_1)); - encrypt_stream( &ctx, scratch, plaintext_1, sizeof(plaintext_1)); - if (memcmp (scratch, ciphertext_1, sizeof (ciphertext_1))) - return "Arcfour encryption test 1 failed."; - arcfour_setkey( &ctx, key_1, sizeof(key_1)); - encrypt_stream(&ctx, scratch, scratch, sizeof(plaintext_1)); /* decrypt */ - if ( memcmp (scratch, plaintext_1, sizeof (plaintext_1))) - return "Arcfour decryption test 1 failed."; - return NULL; + /* Test vector from Cryptlib labeled there: "from the + State/Commerce Department". */ + static byte key_1[] = + { 0x61, 0x8A, 0x63, 0xD2, 0xFB }; + static byte plaintext_1[] = + { 0xDC, 0xEE, 0x4C, 0xF9, 0x2C }; + static const byte ciphertext_1[] = + { 0xF1, 0x38, 0x29, 0xC9, 0xDE }; + + arcfour_setkey( &ctx, key_1, sizeof(key_1)); + encrypt_stream( &ctx, scratch, plaintext_1, sizeof(plaintext_1)); + if ( memcmp (scratch, ciphertext_1, sizeof (ciphertext_1))) + return "Arcfour encryption test 1 failed."; + arcfour_setkey( &ctx, key_1, sizeof(key_1)); + encrypt_stream(&ctx, scratch, scratch, sizeof(plaintext_1)); /* decrypt */ + if ( memcmp (scratch, plaintext_1, sizeof (plaintext_1))) + return "Arcfour decryption test 1 failed."; + return NULL; } - gcry_cipher_spec_t _gcry_cipher_spec_arcfour = { "ARCFOUR", NULL, NULL, 1, 128, sizeof (ARCFOUR_context), arcfour_setkey, NULL, NULL, encrypt_stream, encrypt_stream, }; + diff --git a/cipher/blowfish.c b/cipher/blowfish.c index 11b55411..66b2e8e0 100644 --- a/cipher/blowfish.c +++ b/cipher/blowfish.c @@ -273,133 +273,136 @@ function_F( BLOWFISH_context *bc, u32 x ) #endif #define R(l,r,i) do { l ^= p[i]; r ^= F(l); } while(0) + static void -do_encrypt( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr ) +do_encrypt ( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr ) { #if BLOWFISH_ROUNDS == 16 - u32 xl, xr, *s0, *s1, *s2, *s3, *p; - - xl = *ret_xl; - xr = *ret_xr; - p = bc->p; - s0 = bc->s0; - s1 = bc->s1; - s2 = bc->s2; - s3 = bc->s3; - - R( xl, xr, 0); - R( xr, xl, 1); - R( xl, xr, 2); - R( xr, xl, 3); - R( xl, xr, 4); - R( xr, xl, 5); - R( xl, xr, 6); - R( xr, xl, 7); - R( xl, xr, 8); - R( xr, xl, 9); - R( xl, xr, 10); - R( xr, xl, 11); - R( xl, xr, 12); - R( xr, xl, 13); - R( xl, xr, 14); - R( xr, xl, 15); - - xl ^= p[BLOWFISH_ROUNDS]; - xr ^= p[BLOWFISH_ROUNDS+1]; - - *ret_xl = xr; - *ret_xr = xl; + u32 xl, xr, *s0, *s1, *s2, *s3, *p; + + xl = *ret_xl; + xr = *ret_xr; + p = bc->p; + s0 = bc->s0; + s1 = bc->s1; + s2 = bc->s2; + s3 = bc->s3; + + R( xl, xr, 0); + R( xr, xl, 1); + R( xl, xr, 2); + R( xr, xl, 3); + R( xl, xr, 4); + R( xr, xl, 5); + R( xl, xr, 6); + R( xr, xl, 7); + R( xl, xr, 8); + R( xr, xl, 9); + R( xl, xr, 10); + R( xr, xl, 11); + R( xl, xr, 12); + R( xr, xl, 13); + R( xl, xr, 14); + R( xr, xl, 15); + + xl ^= p[BLOWFISH_ROUNDS]; + xr ^= p[BLOWFISH_ROUNDS+1]; + + *ret_xl = xr; + *ret_xr = xl; #else - u32 xl, xr, temp, *p; - int i; - - xl = *ret_xl; - xr = *ret_xr; - p = bc->p; - - for(i=0; i < BLOWFISH_ROUNDS; i++ ) { - xl ^= p[i]; - xr ^= function_F(bc, xl); - temp = xl; - xl = xr; - xr = temp; + u32 xl, xr, temp, *p; + int i; + + xl = *ret_xl; + xr = *ret_xr; + p = bc->p; + + for(i=0; i < BLOWFISH_ROUNDS; i++ ) + { + xl ^= p[i]; + xr ^= function_F(bc, xl); + temp = xl; + xl = xr; + xr = temp; } - temp = xl; - xl = xr; - xr = temp; + temp = xl; + xl = xr; + xr = temp; - xr ^= p[BLOWFISH_ROUNDS]; - xl ^= p[BLOWFISH_ROUNDS+1]; + xr ^= p[BLOWFISH_ROUNDS]; + xl ^= p[BLOWFISH_ROUNDS+1]; - *ret_xl = xl; - *ret_xr = xr; + *ret_xl = xl; + *ret_xr = xr; #endif } static void -decrypt( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr ) +decrypt ( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr ) { #if BLOWFISH_ROUNDS == 16 - u32 xl, xr, *s0, *s1, *s2, *s3, *p; - - xl = *ret_xl; - xr = *ret_xr; - p = bc->p; - s0 = bc->s0; - s1 = bc->s1; - s2 = bc->s2; - s3 = bc->s3; - - R( xl, xr, 17); - R( xr, xl, 16); - R( xl, xr, 15); - R( xr, xl, 14); - R( xl, xr, 13); - R( xr, xl, 12); - R( xl, xr, 11); - R( xr, xl, 10); - R( xl, xr, 9); - R( xr, xl, 8); - R( xl, xr, 7); - R( xr, xl, 6); - R( xl, xr, 5); - R( xr, xl, 4); - R( xl, xr, 3); - R( xr, xl, 2); - - xl ^= p[1]; - xr ^= p[0]; - - *ret_xl = xr; - *ret_xr = xl; + u32 xl, xr, *s0, *s1, *s2, *s3, *p; + + xl = *ret_xl; + xr = *ret_xr; + p = bc->p; + s0 = bc->s0; + s1 = bc->s1; + s2 = bc->s2; + s3 = bc->s3; + + R( xl, xr, 17); + R( xr, xl, 16); + R( xl, xr, 15); + R( xr, xl, 14); + R( xl, xr, 13); + R( xr, xl, 12); + R( xl, xr, 11); + R( xr, xl, 10); + R( xl, xr, 9); + R( xr, xl, 8); + R( xl, xr, 7); + R( xr, xl, 6); + R( xl, xr, 5); + R( xr, xl, 4); + R( xl, xr, 3); + R( xr, xl, 2); + + xl ^= p[1]; + xr ^= p[0]; + + *ret_xl = xr; + *ret_xr = xl; #else - u32 xl, xr, temp, *p; - int i; - - xl = *ret_xl; - xr = *ret_xr; - p = bc->p; - - for(i=BLOWFISH_ROUNDS+1; i > 1; i-- ) { - xl ^= p[i]; - xr ^= function_F(bc, xl); - temp = xl; - xl = xr; - xr = temp; + u32 xl, xr, temp, *p; + int i; + + xl = *ret_xl; + xr = *ret_xr; + p = bc->p; + + for (i=BLOWFISH_ROUNDS+1; i > 1; i-- ) + { + xl ^= p[i]; + xr ^= function_F(bc, xl); + temp = xl; + xl = xr; + xr = temp; } - temp = xl; - xl = xr; - xr = temp; + temp = xl; + xl = xr; + xr = temp; - xr ^= p[1]; - xl ^= p[0]; + xr ^= p[1]; + xl ^= p[0]; - *ret_xl = xl; - *ret_xr = xr; + *ret_xl = xl; + *ret_xr = xr; #endif } @@ -409,19 +412,19 @@ decrypt( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr ) static void do_encrypt_block ( BLOWFISH_context *bc, byte *outbuf, const byte *inbuf ) { - u32 d1, d2; - - d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; - d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; - do_encrypt( bc, &d1, &d2 ); - outbuf[0] = (d1 >> 24) & 0xff; - outbuf[1] = (d1 >> 16) & 0xff; - outbuf[2] = (d1 >> 8) & 0xff; - outbuf[3] = d1 & 0xff; - outbuf[4] = (d2 >> 24) & 0xff; - outbuf[5] = (d2 >> 16) & 0xff; - outbuf[6] = (d2 >> 8) & 0xff; - outbuf[7] = d2 & 0xff; + u32 d1, d2; + + d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; + d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; + do_encrypt( bc, &d1, &d2 ); + outbuf[0] = (d1 >> 24) & 0xff; + outbuf[1] = (d1 >> 16) & 0xff; + outbuf[2] = (d1 >> 8) & 0xff; + outbuf[3] = d1 & 0xff; + outbuf[4] = (d2 >> 24) & 0xff; + outbuf[5] = (d2 >> 16) & 0xff; + outbuf[6] = (d2 >> 8) & 0xff; + outbuf[7] = d2 & 0xff; } static void @@ -436,19 +439,19 @@ encrypt_block (void *context, byte *outbuf, const byte *inbuf) static void do_decrypt_block (BLOWFISH_context *bc, byte *outbuf, const byte *inbuf) { - u32 d1, d2; - - d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; - d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; - decrypt( bc, &d1, &d2 ); - outbuf[0] = (d1 >> 24) & 0xff; - outbuf[1] = (d1 >> 16) & 0xff; - outbuf[2] = (d1 >> 8) & 0xff; - outbuf[3] = d1 & 0xff; - outbuf[4] = (d2 >> 24) & 0xff; - outbuf[5] = (d2 >> 16) & 0xff; - outbuf[6] = (d2 >> 8) & 0xff; - outbuf[7] = d2 & 0xff; + u32 d1, d2; + + d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; + d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; + decrypt( bc, &d1, &d2 ); + outbuf[0] = (d1 >> 24) & 0xff; + outbuf[1] = (d1 >> 16) & 0xff; + outbuf[2] = (d1 >> 8) & 0xff; + outbuf[3] = d1 & 0xff; + outbuf[4] = (d2 >> 24) & 0xff; + outbuf[5] = (d2 >> 16) & 0xff; + outbuf[6] = (d2 >> 8) & 0xff; + outbuf[7] = d2 & 0xff; } static void @@ -463,29 +466,29 @@ decrypt_block (void *context, byte *outbuf, const byte *inbuf) static const char* selftest(void) { - BLOWFISH_context c; - byte plain[] = "BLOWFISH"; - byte buffer[8]; - byte plain3[] = { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }; - byte key3[] = { 0x41, 0x79, 0x6E, 0xA0, 0x52, 0x61, 0x6E, 0xE4 }; - byte cipher3[] = { 0xE1, 0x13, 0xF4, 0x10, 0x2C, 0xFC, 0xCE, 0x43 }; - - bf_setkey( (void *) &c, "abcdefghijklmnopqrstuvwxyz", 26 ); - encrypt_block( (void *) &c, buffer, plain ); - if( memcmp( buffer, "\x32\x4E\xD0\xFE\xF4\x13\xA2\x03", 8 ) ) - return "Blowfish selftest failed (1)."; - decrypt_block( (void *) &c, buffer, buffer ); - if( memcmp( buffer, plain, 8 ) ) - return "Blowfish selftest failed (2)."; - - bf_setkey( (void *) &c, key3, 8 ); - encrypt_block( (void *) &c, buffer, plain3 ); - if( memcmp( buffer, cipher3, 8 ) ) - return "Blowfish selftest failed (3)."; - decrypt_block( (void *) &c, buffer, buffer ); - if( memcmp( buffer, plain3, 8 ) ) - return "Blowfish selftest failed (4)."; - return NULL; + BLOWFISH_context c; + byte plain[] = "BLOWFISH"; + byte buffer[8]; + byte plain3[] = { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }; + byte key3[] = { 0x41, 0x79, 0x6E, 0xA0, 0x52, 0x61, 0x6E, 0xE4 }; + byte cipher3[] = { 0xE1, 0x13, 0xF4, 0x10, 0x2C, 0xFC, 0xCE, 0x43 }; + + bf_setkey( (void *) &c, "abcdefghijklmnopqrstuvwxyz", 26 ); + encrypt_block( (void *) &c, buffer, plain ); + if( memcmp( buffer, "\x32\x4E\xD0\xFE\xF4\x13\xA2\x03", 8 ) ) + return "Blowfish selftest failed (1)."; + decrypt_block( (void *) &c, buffer, buffer ); + if( memcmp( buffer, plain, 8 ) ) + return "Blowfish selftest failed (2)."; + + bf_setkey( (void *) &c, key3, 8 ); + encrypt_block( (void *) &c, buffer, plain3 ); + if( memcmp( buffer, cipher3, 8 ) ) + return "Blowfish selftest failed (3)."; + decrypt_block( (void *) &c, buffer, buffer ); + if( memcmp( buffer, plain3, 8 ) ) + return "Blowfish selftest failed (4)."; + return NULL; } @@ -493,84 +496,94 @@ selftest(void) static gcry_err_code_t do_bf_setkey (BLOWFISH_context *c, const byte *key, unsigned keylen) { - int i, j; - u32 data, datal, datar; - static int initialized; - static const char *selftest_failed; - - if( !initialized ) { - initialized = 1; - selftest_failed = selftest(); - if( selftest_failed ) - log_error ("%s\n", selftest_failed ); + int i, j; + u32 data, datal, datar; + static int initialized; + static const char *selftest_failed; + + if( !initialized ) + { + initialized = 1; + selftest_failed = selftest(); + if( selftest_failed ) + log_error ("%s\n", selftest_failed ); } - if( selftest_failed ) - return GPG_ERR_SELFTEST_FAILED; - - for(i=0; i < BLOWFISH_ROUNDS+2; i++ ) - c->p[i] = ps[i]; - for(i=0; i < 256; i++ ) { - c->s0[i] = ks0[i]; - c->s1[i] = ks1[i]; - c->s2[i] = ks2[i]; - c->s3[i] = ks3[i]; + if( selftest_failed ) + return GPG_ERR_SELFTEST_FAILED; + + for(i=0; i < BLOWFISH_ROUNDS+2; i++ ) + c->p[i] = ps[i]; + for(i=0; i < 256; i++ ) + { + c->s0[i] = ks0[i]; + c->s1[i] = ks1[i]; + c->s2[i] = ks2[i]; + c->s3[i] = ks3[i]; } - for(i=j=0; i < BLOWFISH_ROUNDS+2; i++ ) { + for(i=j=0; i < BLOWFISH_ROUNDS+2; i++ ) + { #ifdef WORDS_BIGENDIAN - ((byte*)&data)[0] = key[j]; - ((byte*)&data)[1] = key[(j+1)%keylen]; - ((byte*)&data)[2] = key[(j+2)%keylen]; - ((byte*)&data)[3] = key[(j+3)%keylen]; + ((byte*)&data)[0] = key[j]; + ((byte*)&data)[1] = key[(j+1)%keylen]; + ((byte*)&data)[2] = key[(j+2)%keylen]; + ((byte*)&data)[3] = key[(j+3)%keylen]; #else - ((byte*)&data)[3] = key[j]; - ((byte*)&data)[2] = key[(j+1)%keylen]; - ((byte*)&data)[1] = key[(j+2)%keylen]; - ((byte*)&data)[0] = key[(j+3)%keylen]; + ((byte*)&data)[3] = key[j]; + ((byte*)&data)[2] = key[(j+1)%keylen]; + ((byte*)&data)[1] = key[(j+2)%keylen]; + ((byte*)&data)[0] = key[(j+3)%keylen]; #endif - c->p[i] ^= data; - j = (j+4) % keylen; + c->p[i] ^= data; + j = (j+4) % keylen; } - datal = datar = 0; - for(i=0; i < BLOWFISH_ROUNDS+2; i += 2 ) { - do_encrypt( c, &datal, &datar ); - c->p[i] = datal; - c->p[i+1] = datar; + datal = datar = 0; + for(i=0; i < BLOWFISH_ROUNDS+2; i += 2 ) + { + do_encrypt( c, &datal, &datar ); + c->p[i] = datal; + c->p[i+1] = datar; } - for(i=0; i < 256; i += 2 ) { - do_encrypt( c, &datal, &datar ); - c->s0[i] = datal; - c->s0[i+1] = datar; + for(i=0; i < 256; i += 2 ) + { + do_encrypt( c, &datal, &datar ); + c->s0[i] = datal; + c->s0[i+1] = datar; } - for(i=0; i < 256; i += 2 ) { - do_encrypt( c, &datal, &datar ); - c->s1[i] = datal; - c->s1[i+1] = datar; + for(i=0; i < 256; i += 2 ) + { + do_encrypt( c, &datal, &datar ); + c->s1[i] = datal; + c->s1[i+1] = datar; } - for(i=0; i < 256; i += 2 ) { - do_encrypt( c, &datal, &datar ); - c->s2[i] = datal; - c->s2[i+1] = datar; + for(i=0; i < 256; i += 2 ) + { + do_encrypt( c, &datal, &datar ); + c->s2[i] = datal; + c->s2[i+1] = datar; } - for(i=0; i < 256; i += 2 ) { - do_encrypt( c, &datal, &datar ); - c->s3[i] = datal; - c->s3[i+1] = datar; + for(i=0; i < 256; i += 2 ) + { + do_encrypt( c, &datal, &datar ); + c->s3[i] = datal; + c->s3[i+1] = datar; } - /* Check for weak key. A weak key is a key in which a value in */ - /* the P-array (here c) occurs more than once per table. */ - for(i=0; i < 255; i++ ) { - for( j=i+1; j < 256; j++) { - if( (c->s0[i] == c->s0[j]) || (c->s1[i] == c->s1[j]) || - (c->s2[i] == c->s2[j]) || (c->s3[i] == c->s3[j]) ) - return GPG_ERR_WEAK_KEY; - } + /* Check for weak key. A weak key is a key in which a value in + the P-array (here c) occurs more than once per table. */ + for(i=0; i < 255; i++ ) + { + for( j=i+1; j < 256; j++) + { + if( (c->s0[i] == c->s0[j]) || (c->s1[i] == c->s1[j]) || + (c->s2[i] == c->s2[j]) || (c->s3[i] == c->s3[j]) ) + return GPG_ERR_WEAK_KEY; + } } - return GPG_ERR_NO_ERROR; + return GPG_ERR_NO_ERROR; } @@ -583,7 +596,6 @@ bf_setkey (void *context, const byte *key, unsigned keylen) return rc; } - gcry_cipher_spec_t _gcry_cipher_spec_blowfish = { diff --git a/cipher/cast5.c b/cipher/cast5.c index 5dad9193..866d2b4c 100644 --- a/cipher/cast5.c +++ b/cipher/cast5.c @@ -413,7 +413,6 @@ encrypt_block (void *context , byte *outbuf, const byte *inbuf) _gcry_burn_stack (20+4*sizeof(void*)); } - static void do_decrypt_block (CAST5_context *c, byte *outbuf, const byte *inbuf ) @@ -463,7 +462,7 @@ decrypt_block (void *context, byte *outbuf, const byte *inbuf) do_decrypt_block (c, outbuf, inbuf); _gcry_burn_stack (20+4*sizeof(void*)); } - + static const char* selftest(void) @@ -511,7 +510,6 @@ selftest(void) return NULL; } - static void key_schedule( u32 *x, u32 *z, u32 *k ) @@ -566,42 +564,43 @@ do_cast_setkey( CAST5_context *c, const byte *key, unsigned keylen ) { static int initialized; static const char* selftest_failed; - int i; - u32 x[4]; - u32 z[4]; - u32 k[16]; - - if( !initialized ) { - initialized = 1; - selftest_failed = selftest(); - if( selftest_failed ) - log_error ("CAST5 selftest failed (%s).\n", selftest_failed ); + int i; + u32 x[4]; + u32 z[4]; + u32 k[16]; + + if( !initialized ) + { + initialized = 1; + selftest_failed = selftest(); + if( selftest_failed ) + log_error ("CAST5 selftest failed (%s).\n", selftest_failed ); } - if( selftest_failed ) - return GPG_ERR_SELFTEST_FAILED; + if( selftest_failed ) + return GPG_ERR_SELFTEST_FAILED; - if( keylen != 16 ) - return GPG_ERR_INV_KEYLEN; + if( keylen != 16 ) + return GPG_ERR_INV_KEYLEN; - x[0] = key[0] << 24 | key[1] << 16 | key[2] << 8 | key[3]; - x[1] = key[4] << 24 | key[5] << 16 | key[6] << 8 | key[7]; - x[2] = key[8] << 24 | key[9] << 16 | key[10] << 8 | key[11]; - x[3] = key[12] << 24 | key[13] << 16 | key[14] << 8 | key[15]; + x[0] = key[0] << 24 | key[1] << 16 | key[2] << 8 | key[3]; + x[1] = key[4] << 24 | key[5] << 16 | key[6] << 8 | key[7]; + x[2] = key[8] << 24 | key[9] << 16 | key[10] << 8 | key[11]; + x[3] = key[12] << 24 | key[13] << 16 | key[14] << 8 | key[15]; - key_schedule( x, z, k ); - for(i=0; i < 16; i++ ) - c->Km[i] = k[i]; - key_schedule( x, z, k ); - for(i=0; i < 16; i++ ) - c->Kr[i] = k[i] & 0x1f; + key_schedule( x, z, k ); + for(i=0; i < 16; i++ ) + c->Km[i] = k[i]; + key_schedule( x, z, k ); + for(i=0; i < 16; i++ ) + c->Kr[i] = k[i] & 0x1f; - memset(&x,0, sizeof x); - memset(&z,0, sizeof z); - memset(&k,0, sizeof k); + memset(&x,0, sizeof x); + memset(&z,0, sizeof z); + memset(&k,0, sizeof k); #undef xi #undef zi - return GPG_ERR_NO_ERROR; + return GPG_ERR_NO_ERROR; } static gcry_err_code_t @@ -612,7 +611,7 @@ cast_setkey (void *context, const byte *key, unsigned keylen ) _gcry_burn_stack (96+7*sizeof(void*)); return rc; } - + gcry_cipher_spec_t _gcry_cipher_spec_cast5 = { diff --git a/cipher/des.c b/cipher/des.c index 7e3d0841..a0d98263 100644 --- a/cipher/des.c +++ b/cipher/des.c @@ -1,5 +1,5 @@ /* des.c - DES and Triple-DES encryption/decryption Algorithm - * Copyright (C) 1998, 1999, 2001, 2002, 2003 Free Software Foundation, Inc. + * Copyright (C) 1998, 1999, 2001, 2002, 2003 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * @@ -158,9 +158,12 @@ tripledes_ctx[1]; static void des_key_schedule (const byte *, u32 *); static int des_setkey (struct _des_ctx *, const byte *); static int des_ecb_crypt (struct _des_ctx *, const byte *, byte *, int); -static int tripledes_set2keys (struct _tripledes_ctx *, const byte *, const byte *); -static int tripledes_set3keys (struct _tripledes_ctx *, const byte *, const byte *, const byte *); -static int tripledes_ecb_crypt (struct _tripledes_ctx *, const byte *, byte *, int); +static int tripledes_set2keys (struct _tripledes_ctx *, + const byte *, const byte *); +static int tripledes_set3keys (struct _tripledes_ctx *, + const byte *, const byte *, const byte *); +static int tripledes_ecb_crypt (struct _tripledes_ctx *, + const byte *, byte *, int); static int is_weak_key ( const byte *key ); static const char *selftest (void); @@ -447,23 +450,23 @@ static unsigned char weak_keys_chksum[20] = { /* * Macros to convert 8 bytes from/to 32bit words. */ -#define READ_64BIT_DATA(data, left, right) \ - left = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; \ +#define READ_64BIT_DATA(data, left, right) \ + left = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; \ right = (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7]; -#define WRITE_64BIT_DATA(data, left, right) \ - data[0] = (left >> 24) &0xff; data[1] = (left >> 16) &0xff; \ - data[2] = (left >> 8) &0xff; data[3] = left &0xff; \ - data[4] = (right >> 24) &0xff; data[5] = (right >> 16) &0xff; \ +#define WRITE_64BIT_DATA(data, left, right) \ + data[0] = (left >> 24) &0xff; data[1] = (left >> 16) &0xff; \ + data[2] = (left >> 8) &0xff; data[3] = left &0xff; \ + data[4] = (right >> 24) &0xff; data[5] = (right >> 16) &0xff; \ data[6] = (right >> 8) &0xff; data[7] = right &0xff; /* * Handy macros for encryption and decryption of data */ -#define des_ecb_encrypt(ctx, from, to) des_ecb_crypt(ctx, from, to, 0) -#define des_ecb_decrypt(ctx, from, to) des_ecb_crypt(ctx, from, to, 1) -#define tripledes_ecb_encrypt(ctx, from, to) tripledes_ecb_crypt(ctx, from, to, 0) -#define tripledes_ecb_decrypt(ctx, from, to) tripledes_ecb_crypt(ctx, from, to, 1) +#define des_ecb_encrypt(ctx, from, to) des_ecb_crypt(ctx, from, to, 0) +#define des_ecb_decrypt(ctx, from, to) des_ecb_crypt(ctx, from, to, 1) +#define tripledes_ecb_encrypt(ctx, from, to) tripledes_ecb_crypt(ctx,from,to,0) +#define tripledes_ecb_decrypt(ctx, from, to) tripledes_ecb_crypt(ctx,from,to,1) @@ -492,75 +495,84 @@ des_key_schedule (const byte * rawkey, u32 * subkey) DO_PERMUTATION (right, work, left, 4, 0x0f0f0f0f) DO_PERMUTATION (right, work, left, 0, 0x10101010) - left = (leftkey_swap[(left >> 0) & 0xf] << 3) | (leftkey_swap[(left >> 8) & 0xf] << 2) - | (leftkey_swap[(left >> 16) & 0xf] << 1) | (leftkey_swap[(left >> 24) & 0xf]) - | (leftkey_swap[(left >> 5) & 0xf] << 7) | (leftkey_swap[(left >> 13) & 0xf] << 6) - | (leftkey_swap[(left >> 21) & 0xf] << 5) | (leftkey_swap[(left >> 29) & 0xf] << 4); + left = ((leftkey_swap[(left >> 0) & 0xf] << 3) + | (leftkey_swap[(left >> 8) & 0xf] << 2) + | (leftkey_swap[(left >> 16) & 0xf] << 1) + | (leftkey_swap[(left >> 24) & 0xf]) + | (leftkey_swap[(left >> 5) & 0xf] << 7) + | (leftkey_swap[(left >> 13) & 0xf] << 6) + | (leftkey_swap[(left >> 21) & 0xf] << 5) + | (leftkey_swap[(left >> 29) & 0xf] << 4)); left &= 0x0fffffff; - right = (rightkey_swap[(right >> 1) & 0xf] << 3) | (rightkey_swap[(right >> 9) & 0xf] << 2) - | (rightkey_swap[(right >> 17) & 0xf] << 1) | (rightkey_swap[(right >> 25) & 0xf]) - | (rightkey_swap[(right >> 4) & 0xf] << 7) | (rightkey_swap[(right >> 12) & 0xf] << 6) - | (rightkey_swap[(right >> 20) & 0xf] << 5) | (rightkey_swap[(right >> 28) & 0xf] << 4); + right = ((rightkey_swap[(right >> 1) & 0xf] << 3) + | (rightkey_swap[(right >> 9) & 0xf] << 2) + | (rightkey_swap[(right >> 17) & 0xf] << 1) + | (rightkey_swap[(right >> 25) & 0xf]) + | (rightkey_swap[(right >> 4) & 0xf] << 7) + | (rightkey_swap[(right >> 12) & 0xf] << 6) + | (rightkey_swap[(right >> 20) & 0xf] << 5) + | (rightkey_swap[(right >> 28) & 0xf] << 4)); right &= 0x0fffffff; for (round = 0; round < 16; ++round) { - left = ((left << encrypt_rotate_tab[round]) | (left >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff; - right = ((right << encrypt_rotate_tab[round]) | (right >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff; - - *subkey++ = ((left << 4) & 0x24000000) - | ((left << 28) & 0x10000000) - | ((left << 14) & 0x08000000) - | ((left << 18) & 0x02080000) - | ((left << 6) & 0x01000000) - | ((left << 9) & 0x00200000) - | ((left >> 1) & 0x00100000) - | ((left << 10) & 0x00040000) - | ((left << 2) & 0x00020000) - | ((left >> 10) & 0x00010000) - | ((right >> 13) & 0x00002000) - | ((right >> 4) & 0x00001000) - | ((right << 6) & 0x00000800) - | ((right >> 1) & 0x00000400) - | ((right >> 14) & 0x00000200) - | (right & 0x00000100) - | ((right >> 5) & 0x00000020) - | ((right >> 10) & 0x00000010) - | ((right >> 3) & 0x00000008) - | ((right >> 18) & 0x00000004) - | ((right >> 26) & 0x00000002) - | ((right >> 24) & 0x00000001); - - *subkey++ = ((left << 15) & 0x20000000) - | ((left << 17) & 0x10000000) - | ((left << 10) & 0x08000000) - | ((left << 22) & 0x04000000) - | ((left >> 2) & 0x02000000) - | ((left << 1) & 0x01000000) - | ((left << 16) & 0x00200000) - | ((left << 11) & 0x00100000) - | ((left << 3) & 0x00080000) - | ((left >> 6) & 0x00040000) - | ((left << 15) & 0x00020000) - | ((left >> 4) & 0x00010000) - | ((right >> 2) & 0x00002000) - | ((right << 8) & 0x00001000) - | ((right >> 14) & 0x00000808) - | ((right >> 9) & 0x00000400) - | ((right) & 0x00000200) - | ((right << 7) & 0x00000100) - | ((right >> 7) & 0x00000020) - | ((right >> 3) & 0x00000011) - | ((right << 2) & 0x00000004) - | ((right >> 21) & 0x00000002); + left = ((left << encrypt_rotate_tab[round]) + | (left >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff; + right = ((right << encrypt_rotate_tab[round]) + | (right >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff; + + *subkey++ = (((left << 4) & 0x24000000) + | ((left << 28) & 0x10000000) + | ((left << 14) & 0x08000000) + | ((left << 18) & 0x02080000) + | ((left << 6) & 0x01000000) + | ((left << 9) & 0x00200000) + | ((left >> 1) & 0x00100000) + | ((left << 10) & 0x00040000) + | ((left << 2) & 0x00020000) + | ((left >> 10) & 0x00010000) + | ((right >> 13) & 0x00002000) + | ((right >> 4) & 0x00001000) + | ((right << 6) & 0x00000800) + | ((right >> 1) & 0x00000400) + | ((right >> 14) & 0x00000200) + | (right & 0x00000100) + | ((right >> 5) & 0x00000020) + | ((right >> 10) & 0x00000010) + | ((right >> 3) & 0x00000008) + | ((right >> 18) & 0x00000004) + | ((right >> 26) & 0x00000002) + | ((right >> 24) & 0x00000001)); + + *subkey++ = (((left << 15) & 0x20000000) + | ((left << 17) & 0x10000000) + | ((left << 10) & 0x08000000) + | ((left << 22) & 0x04000000) + | ((left >> 2) & 0x02000000) + | ((left << 1) & 0x01000000) + | ((left << 16) & 0x00200000) + | ((left << 11) & 0x00100000) + | ((left << 3) & 0x00080000) + | ((left >> 6) & 0x00040000) + | ((left << 15) & 0x00020000) + | ((left >> 4) & 0x00010000) + | ((right >> 2) & 0x00002000) + | ((right << 8) & 0x00001000) + | ((right >> 14) & 0x00000808) + | ((right >> 9) & 0x00000400) + | ((right) & 0x00000200) + | ((right << 7) & 0x00000100) + | ((right >> 7) & 0x00000020) + | ((right >> 3) & 0x00000011) + | ((right << 2) & 0x00000004) + | ((right >> 21) & 0x00000002)); } } - /* * Fill a DES context with subkeys calculated from a 64bit key. * Does not check parity bits, but simply ignore them. @@ -713,11 +725,13 @@ tripledes_set3keys (struct _tripledes_ctx *ctx, /* - * Electronic Codebook Mode Triple-DES encryption/decryption of data according to 'mode'. - * Sometimes this mode is named 'EDE' mode (Encryption-Decryption-Encryption). + * Electronic Codebook Mode Triple-DES encryption/decryption of data + * according to 'mode'. Sometimes this mode is named 'EDE' mode + * (Encryption-Decryption-Encryption). */ static int -tripledes_ecb_crypt (struct _tripledes_ctx *ctx, const byte * from, byte * to, int mode) +tripledes_ecb_crypt (struct _tripledes_ctx *ctx, const byte * from, + byte * to, int mode) { u32 left, right, work; u32 *keys; @@ -812,7 +826,7 @@ selftest (void) * need this. */ if (sizeof (u32) != 4) - return "Wrong word size for DES configured."; + return "Wrong word size for DES configured."; /* * DES Maintenance Test @@ -820,11 +834,11 @@ selftest (void) { int i; byte key[8] = - {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55}; + {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55}; byte input[8] = - {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; byte result[8] = - {0x24, 0x6e, 0x9d, 0xb9, 0xc5, 0x50, 0x38, 0x1a}; + {0x24, 0x6e, 0x9d, 0xb9, 0xc5, 0x50, 0x38, 0x1a}; byte temp1[8], temp2[8], temp3[8]; des_ctx des; @@ -844,18 +858,18 @@ selftest (void) /* - * Self made Triple-DES test (Does somebody known an official test?) + * Self made Triple-DES test (Does somebody know an official test?) */ { int i; byte input[8] = - {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}; + {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}; byte key1[8] = - {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0}; + {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0}; byte key2[8] = - {0x11, 0x22, 0x33, 0x44, 0xff, 0xaa, 0xcc, 0xdd}; + {0x11, 0x22, 0x33, 0x44, 0xff, 0xaa, 0xcc, 0xdd}; byte result[8] = - {0x7b, 0x38, 0x3b, 0x23, 0xa2, 0x7d, 0x26, 0xd3}; + {0x7b, 0x38, 0x3b, 0x23, 0xa2, 0x7d, 0x26, 0xd3}; tripledes_ctx des3; @@ -870,101 +884,108 @@ selftest (void) if (memcmp (input, result, 8)) return "Triple-DES test failed."; } + + /* + * More Triple-DES test. These are testvectors as used by SSLeay, + * thanks to Jeroen C. van Gelderen. + */ + { + struct { byte key[24]; byte plain[8]; byte cipher[8]; } testdata[] = { + { { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 }, + { 0x95,0xF8,0xA5,0xE5,0xDD,0x31,0xD9,0x00 }, + { 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } + }, + + { { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 }, + { 0x9D,0x64,0x55,0x5A,0x9A,0x10,0xB8,0x52, }, + { 0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00 } + }, + { { 0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E, + 0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E, + 0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E }, + { 0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A }, + { 0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A } + }, + { { 0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6, + 0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6, + 0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6 }, + { 0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2 }, + { 0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95 } + }, + { { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, + 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, + 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF }, + { 0x73,0x6F,0x6D,0x65,0x64,0x61,0x74,0x61 }, + { 0x3D,0x12,0x4F,0xE2,0x19,0x8B,0xA3,0x18 } + }, + { { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF }, + { 0x73,0x6F,0x6D,0x65,0x64,0x61,0x74,0x61 }, + { 0xFB,0xAB,0xA1,0xFF,0x9D,0x05,0xE9,0xB1 } + }, + { { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10 }, + { 0x73,0x6F,0x6D,0x65,0x64,0x61,0x74,0x61 }, + { 0x18,0xd7,0x48,0xe5,0x63,0x62,0x05,0x72 } + }, + { { 0x03,0x52,0x02,0x07,0x67,0x20,0x82,0x17, + 0x86,0x02,0x87,0x66,0x59,0x08,0x21,0x98, + 0x64,0x05,0x6A,0xBD,0xFE,0xA9,0x34,0x57 }, + { 0x73,0x71,0x75,0x69,0x67,0x67,0x6C,0x65 }, + { 0xc0,0x7d,0x2a,0x0f,0xa5,0x66,0xfa,0x30 } + }, + { { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x80,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02 }, + { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, + { 0xe6,0xe6,0xdd,0x5b,0x7e,0x72,0x29,0x74 } + }, + { { 0x10,0x46,0x10,0x34,0x89,0x98,0x80,0x20, + 0x91,0x07,0xD0,0x15,0x89,0x19,0x01,0x01, + 0x19,0x07,0x92,0x10,0x98,0x1A,0x01,0x01 }, + { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, + { 0xe1,0xef,0x62,0xc3,0x32,0xfe,0x82,0x5b } + } + }; - /* - * More Triple-DES test. These are testvectors as used by SSLeay, - * thanks to Jeroen C. van Gelderen. - */ - { struct { byte key[24]; byte plain[8]; byte cipher[8]; } testdata[] = { - { { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, - 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, - 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 }, - { 0x95,0xF8,0xA5,0xE5,0xDD,0x31,0xD9,0x00 }, - { 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } - }, - - { { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, - 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, - 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 }, - { 0x9D,0x64,0x55,0x5A,0x9A,0x10,0xB8,0x52, }, - { 0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00 } - }, - { { 0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E, - 0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E, - 0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E }, - { 0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A }, - { 0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A } - }, - { { 0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6, - 0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6, - 0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6 }, - { 0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2 }, - { 0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95 } - }, - { { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, - 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, - 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF }, - { 0x73,0x6F,0x6D,0x65,0x64,0x61,0x74,0x61 }, - { 0x3D,0x12,0x4F,0xE2,0x19,0x8B,0xA3,0x18 } - }, - { { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, - 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, - 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF }, - { 0x73,0x6F,0x6D,0x65,0x64,0x61,0x74,0x61 }, - { 0xFB,0xAB,0xA1,0xFF,0x9D,0x05,0xE9,0xB1 } - }, - { { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, - 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, - 0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10 }, - { 0x73,0x6F,0x6D,0x65,0x64,0x61,0x74,0x61 }, - { 0x18,0xd7,0x48,0xe5,0x63,0x62,0x05,0x72 } - }, - { { 0x03,0x52,0x02,0x07,0x67,0x20,0x82,0x17, - 0x86,0x02,0x87,0x66,0x59,0x08,0x21,0x98, - 0x64,0x05,0x6A,0xBD,0xFE,0xA9,0x34,0x57 }, - { 0x73,0x71,0x75,0x69,0x67,0x67,0x6C,0x65 }, - { 0xc0,0x7d,0x2a,0x0f,0xa5,0x66,0xfa,0x30 } - }, - { { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, - 0x80,0x01,0x01,0x01,0x01,0x01,0x01,0x01, - 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02 }, - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - { 0xe6,0xe6,0xdd,0x5b,0x7e,0x72,0x29,0x74 } - }, - { { 0x10,0x46,0x10,0x34,0x89,0x98,0x80,0x20, - 0x91,0x07,0xD0,0x15,0x89,0x19,0x01,0x01, - 0x19,0x07,0x92,0x10,0x98,0x1A,0x01,0x01 }, - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - { 0xe1,0xef,0x62,0xc3,0x32,0xfe,0x82,0x5b } - } - }; - - byte result[8]; - int i; - static char error[80]; - tripledes_ctx des3; - - for (i=0; i<sizeof(testdata)/sizeof(*testdata); ++i) { - tripledes_set3keys (des3, testdata[i].key, testdata[i].key + 8, testdata[i].key + 16); - - tripledes_ecb_encrypt (des3, testdata[i].plain, result); - if (memcmp (testdata[i].cipher, result, 8)) { - sprintf (error, "Triple-DES SSLeay test pattern no. %d failend on encryption.", i+1); - return error; - } - - tripledes_ecb_decrypt (des3, testdata[i].cipher, result); - if (memcmp (testdata[i].plain, result, 8)) { - sprintf (error, "Triple-DES SSLeay test pattern no. %d failend on decryption.", i+1); - return error; - } - } - } + byte result[8]; + int i; + static char error[80]; + tripledes_ctx des3; + + for (i=0; i<sizeof(testdata)/sizeof(*testdata); ++i) + { + tripledes_set3keys (des3, testdata[i].key, + testdata[i].key + 8, testdata[i].key + 16); + + tripledes_ecb_encrypt (des3, testdata[i].plain, result); + if (memcmp (testdata[i].cipher, result, 8)) + { + sprintf (error, "Triple-DES SSLeay test pattern no. %d " + "failed on encryption.", i+1); + return error; + } + + tripledes_ecb_decrypt (des3, testdata[i].cipher, result); + if (memcmp (testdata[i].plain, result, 8)) + { + sprintf (error, "Triple-DES SSLeay test pattern no. %d " + "failed on decryption.", i+1); + return error; + } + } + } /* * Check the weak key detection. We simply assume that the table * with weak keys is ok and check every key in the table if it is - * detected... (This test is a little bit stupid) + * detected... (This test is a little bit stupid). */ { int i; @@ -983,8 +1004,8 @@ selftest (void) return "weak key table defect"; for (i = 0; i < 64; ++i) - if (!is_weak_key(weak_keys[i])) - return "DES weak key detection failed"; + if (!is_weak_key(weak_keys[i])) + return "DES weak key detection failed"; } return 0; @@ -996,18 +1017,19 @@ do_tripledes_setkey ( void *context, const byte *key, unsigned keylen ) { struct _tripledes_ctx *ctx = (struct _tripledes_ctx *) context; - if( keylen != 24 ) - return GPG_ERR_INV_KEYLEN; + if( keylen != 24 ) + return GPG_ERR_INV_KEYLEN; - tripledes_set3keys ( ctx, key, key+8, key+16); + tripledes_set3keys ( ctx, key, key+8, key+16); - if( is_weak_key( key ) || is_weak_key( key+8 ) || is_weak_key( key+16 ) ) { - _gcry_burn_stack (64); - return GPG_ERR_WEAK_KEY; + if( is_weak_key( key ) || is_weak_key( key+8 ) || is_weak_key( key+16 ) ) + { + _gcry_burn_stack (64); + return GPG_ERR_WEAK_KEY; } - _gcry_burn_stack (64); + _gcry_burn_stack (64); - return GPG_ERR_NO_ERROR; + return GPG_ERR_NO_ERROR; } diff --git a/cipher/dsa.c b/cipher/dsa.c index 11908d4f..c3b4c82e 100644 --- a/cipher/dsa.c +++ b/cipher/dsa.c @@ -1,5 +1,5 @@ /* dsa.c - DSA signature scheme - * Copyright (C) 1998, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + * Copyright (C) 1998, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * @@ -50,15 +50,20 @@ typedef struct static gcry_mpi_t gen_k (gcry_mpi_t q); static void test_keys (DSA_secret_key *sk, unsigned qbits); static int check_secret_key (DSA_secret_key *sk); -static void generate (DSA_secret_key *sk, unsigned nbits, gcry_mpi_t **ret_factors); -static void sign (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input, DSA_secret_key *skey); -static int verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input, DSA_public_key *pkey); +static void generate (DSA_secret_key *sk, unsigned nbits, + gcry_mpi_t **ret_factors); +static void sign (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input, + DSA_secret_key *skey); +static int verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input, + DSA_public_key *pkey); static void (*progress_cb) (void *,const char *, int, int, int ); static void *progress_cb_data; + void -_gcry_register_pk_dsa_progress (void (*cb) (void *, const char *, int, int, int), +_gcry_register_pk_dsa_progress (void (*cb) (void *, const char *, + int, int, int), void *cb_data) { progress_cb = cb; @@ -74,281 +79,290 @@ progress (int c) } - -/**************** - * Generate a random secret exponent k less than q +/* + * Generate a random secret exponent k less than q. */ static gcry_mpi_t gen_k( gcry_mpi_t q ) { - gcry_mpi_t k = mpi_alloc_secure( mpi_get_nlimbs(q) ); - unsigned int nbits = mpi_get_nbits(q); - unsigned int nbytes = (nbits+7)/8; - char *rndbuf = NULL; - - if( DBG_CIPHER ) - log_debug("choosing a random k "); - for(;;) { - if( DBG_CIPHER ) - progress('.'); - - if( !rndbuf || nbits < 32 ) { - gcry_free(rndbuf); - rndbuf = gcry_random_bytes_secure( (nbits+7)/8, - GCRY_STRONG_RANDOM ); + gcry_mpi_t k = mpi_alloc_secure( mpi_get_nlimbs(q) ); + unsigned int nbits = mpi_get_nbits(q); + unsigned int nbytes = (nbits+7)/8; + char *rndbuf = NULL; + + if ( DBG_CIPHER ) + log_debug("choosing a random k "); + for (;;) + { + if( DBG_CIPHER ) + progress('.'); + + if ( !rndbuf || nbits < 32 ) + { + gcry_free(rndbuf); + rndbuf = gcry_random_bytes_secure( (nbits+7)/8, GCRY_STRONG_RANDOM ); } - else { /* change only some of the higher bits */ - /* we could imporove this by directly requesting more memory - * at the first call to get_random_bytes() and use this the here - * maybe it is easier to do this directly in random.c */ - char *pp = gcry_random_bytes_secure( 4, GCRY_STRONG_RANDOM ); - memcpy( rndbuf,pp, 4 ); - gcry_free(pp); + else + { /* Change only some of the higher bits. We could improve + this by directly requesting more memory at the first call + to get_random_bytes() and use this the here maybe it is + easier to do this directly in random.c. */ + char *pp = gcry_random_bytes_secure( 4, GCRY_STRONG_RANDOM ); + memcpy( rndbuf,pp, 4 ); + gcry_free(pp); } - _gcry_mpi_set_buffer( k, rndbuf, nbytes, 0 ); - if( mpi_test_bit( k, nbits-1 ) ) - mpi_set_highbit( k, nbits-1 ); - else { - mpi_set_highbit( k, nbits-1 ); - mpi_clear_bit( k, nbits-1 ); + _gcry_mpi_set_buffer( k, rndbuf, nbytes, 0 ); + if ( mpi_test_bit( k, nbits-1 ) ) + mpi_set_highbit( k, nbits-1 ); + else + { + mpi_set_highbit( k, nbits-1 ); + mpi_clear_bit( k, nbits-1 ); } - if( !(mpi_cmp( k, q ) < 0) ) { /* check: k < q */ - if( DBG_CIPHER ) - progress('+'); - continue; /* no */ - } - if( !(mpi_cmp_ui( k, 0 ) > 0) ) { /* check: k > 0 */ - if( DBG_CIPHER ) - progress('-'); - continue; /* no */ - } - break; /* okay */ + if( !(mpi_cmp( k, q ) < 0) ) /* check: k < q */ + { + if( DBG_CIPHER ) + progress('+'); + continue; /* no */ + } + if( !(mpi_cmp_ui( k, 0 ) > 0) ) /* check: k > 0 */ + { + if( DBG_CIPHER ) + progress('-'); + continue; /* no */ + } + break; /* okay */ } - gcry_free(rndbuf); - if( DBG_CIPHER ) - progress('\n'); - - return k; + gcry_free(rndbuf); + if( DBG_CIPHER ) + progress('\n'); + + return k; } static void test_keys( DSA_secret_key *sk, unsigned qbits ) { - DSA_public_key pk; - gcry_mpi_t test = gcry_mpi_new ( qbits ); - gcry_mpi_t out1_a = gcry_mpi_new ( qbits ); - gcry_mpi_t out1_b = gcry_mpi_new ( qbits ); - - pk.p = sk->p; - pk.q = sk->q; - pk.g = sk->g; - pk.y = sk->y; - gcry_mpi_randomize( test, qbits, GCRY_WEAK_RANDOM ); - - sign( out1_a, out1_b, test, sk ); - if( !verify( out1_a, out1_b, test, &pk ) ) - log_fatal("DSA:: sign, verify failed\n"); - - gcry_mpi_release ( test ); - gcry_mpi_release ( out1_a ); - gcry_mpi_release ( out1_b ); + DSA_public_key pk; + gcry_mpi_t test = gcry_mpi_new ( qbits ); + gcry_mpi_t out1_a = gcry_mpi_new ( qbits ); + gcry_mpi_t out1_b = gcry_mpi_new ( qbits ); + + pk.p = sk->p; + pk.q = sk->q; + pk.g = sk->g; + pk.y = sk->y; + gcry_mpi_randomize( test, qbits, GCRY_WEAK_RANDOM ); + + sign( out1_a, out1_b, test, sk ); + if( !verify( out1_a, out1_b, test, &pk ) ) + log_fatal("DSA:: sign, verify failed\n"); + + gcry_mpi_release ( test ); + gcry_mpi_release ( out1_a ); + gcry_mpi_release ( out1_b ); } -/**************** - * Generate a DSA key pair with a key of size NBITS - * Returns: 2 structures filled with all needed values - * and an array with the n-1 factors of (p-1) +/* + Generate a DSA key pair with a key of size NBITS. + Returns: 2 structures filled with all needed values + and an array with the n-1 factors of (p-1) */ static void generate( DSA_secret_key *sk, unsigned nbits, gcry_mpi_t **ret_factors ) { - gcry_mpi_t p; /* the prime */ - gcry_mpi_t q; /* the 160 bit prime factor */ - gcry_mpi_t g; /* the generator */ - gcry_mpi_t y; /* g^x mod p */ - gcry_mpi_t x; /* the secret exponent */ - gcry_mpi_t h, e; /* helper */ - unsigned qbits; - byte *rndbuf; - - assert( nbits >= 512 && nbits <= 1024 ); - - qbits = 160; - p = _gcry_generate_elg_prime( 1, nbits, qbits, NULL, ret_factors ); - /* get q out of factors */ - q = mpi_copy((*ret_factors)[0]); - if( mpi_get_nbits(q) != qbits ) - BUG(); - - /* find a generator g (h and e are helpers)*/ - /* e = (p-1)/q */ - e = mpi_alloc( mpi_get_nlimbs(p) ); - mpi_sub_ui( e, p, 1 ); - mpi_fdiv_q( e, e, q ); - g = mpi_alloc( mpi_get_nlimbs(p) ); - h = mpi_alloc_set_ui( 1 ); /* we start with 2 */ - do { - mpi_add_ui( h, h, 1 ); - /* g = h^e mod p */ - gcry_mpi_powm( g, h, e, p ); - } while( !mpi_cmp_ui( g, 1 ) ); /* continue until g != 1 */ - - /* select a random number which has these properties: - * 0 < x < q-1 - * This must be a very good random number because this - * is the secret part. */ - if( DBG_CIPHER ) - log_debug("choosing a random x "); - assert( qbits >= 160 ); - x = mpi_alloc_secure( mpi_get_nlimbs(q) ); - mpi_sub_ui( h, q, 1 ); /* put q-1 into h */ - rndbuf = NULL; - do { - if( DBG_CIPHER ) - progress('.'); - if( !rndbuf ) - rndbuf = gcry_random_bytes_secure( (qbits+7)/8, - GCRY_VERY_STRONG_RANDOM ); - else { /* change only some of the higher bits (= 2 bytes)*/ - char *r = gcry_random_bytes_secure( 2, - GCRY_VERY_STRONG_RANDOM ); - memcpy(rndbuf, r, 2 ); - gcry_free(r); - } - _gcry_mpi_set_buffer( x, rndbuf, (qbits+7)/8, 0 ); - mpi_clear_highbit( x, qbits+1 ); - } while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, h )<0 ) ); - gcry_free(rndbuf); - mpi_free( e ); - mpi_free( h ); - - /* y = g^x mod p */ - y = mpi_alloc( mpi_get_nlimbs(p) ); - gcry_mpi_powm( y, g, x, p ); - - if( DBG_CIPHER ) { - progress('\n'); - log_mpidump("dsa p= ", p ); - log_mpidump("dsa q= ", q ); - log_mpidump("dsa g= ", g ); - log_mpidump("dsa y= ", y ); - log_mpidump("dsa x= ", x ); + gcry_mpi_t p; /* the prime */ + gcry_mpi_t q; /* the 160 bit prime factor */ + gcry_mpi_t g; /* the generator */ + gcry_mpi_t y; /* g^x mod p */ + gcry_mpi_t x; /* the secret exponent */ + gcry_mpi_t h, e; /* helper */ + unsigned qbits; + byte *rndbuf; + + assert( nbits >= 512 && nbits <= 1024 ); + + qbits = 160; + p = _gcry_generate_elg_prime( 1, nbits, qbits, NULL, ret_factors ); + /* get q out of factors */ + q = mpi_copy((*ret_factors)[0]); + if( mpi_get_nbits(q) != qbits ) + BUG(); + + /* Find a generator g (h and e are helpers). + e = (p-1)/q */ + e = mpi_alloc( mpi_get_nlimbs(p) ); + mpi_sub_ui( e, p, 1 ); + mpi_fdiv_q( e, e, q ); + g = mpi_alloc( mpi_get_nlimbs(p) ); + h = mpi_alloc_set_ui( 1 ); /* we start with 2 */ + do + { + mpi_add_ui( h, h, 1 ); + /* g = h^e mod p */ + gcry_mpi_powm( g, h, e, p ); + } + while( !mpi_cmp_ui( g, 1 ) ); /* continue until g != 1 */ + + /* Select a random number which has these properties: + * 0 < x < q-1 + * This must be a very good random number because this + * is the secret part. */ + if( DBG_CIPHER ) + log_debug("choosing a random x "); + assert( qbits >= 160 ); + x = mpi_alloc_secure( mpi_get_nlimbs(q) ); + mpi_sub_ui( h, q, 1 ); /* put q-1 into h */ + rndbuf = NULL; + do + { + if( DBG_CIPHER ) + progress('.'); + if( !rndbuf ) + rndbuf = gcry_random_bytes_secure( (qbits+7)/8, + GCRY_VERY_STRONG_RANDOM ); + else + { /* Change only some of the higher bits (= 2 bytes)*/ + char *r = gcry_random_bytes_secure (2, GCRY_VERY_STRONG_RANDOM); + memcpy(rndbuf, r, 2 ); + gcry_free(r); + } + + _gcry_mpi_set_buffer( x, rndbuf, (qbits+7)/8, 0 ); + mpi_clear_highbit( x, qbits+1 ); + } + while ( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, h )<0 ) ); + gcry_free(rndbuf); + mpi_free( e ); + mpi_free( h ); + + /* y = g^x mod p */ + y = mpi_alloc( mpi_get_nlimbs(p) ); + gcry_mpi_powm( y, g, x, p ); + + if( DBG_CIPHER ) + { + progress('\n'); + log_mpidump("dsa p= ", p ); + log_mpidump("dsa q= ", q ); + log_mpidump("dsa g= ", g ); + log_mpidump("dsa y= ", y ); + log_mpidump("dsa x= ", x ); } - /* copy the stuff to the key structures */ - sk->p = p; - sk->q = q; - sk->g = g; - sk->y = y; - sk->x = x; + /* Copy the stuff to the key structures. */ + sk->p = p; + sk->q = q; + sk->g = g; + sk->y = y; + sk->x = x; - /* now we can test our keys (this should never fail!) */ - test_keys( sk, qbits ); + /* Now we can test our keys (this should never fail!). */ + test_keys( sk, qbits ); } -/**************** - * Test whether the secret key is valid. - * Returns: if this is a valid key. +/* + Test whether the secret key is valid. + Returns: if this is a valid key. */ static int check_secret_key( DSA_secret_key *sk ) { - int rc; - gcry_mpi_t y = mpi_alloc( mpi_get_nlimbs(sk->y) ); + int rc; + gcry_mpi_t y = mpi_alloc( mpi_get_nlimbs(sk->y) ); - gcry_mpi_powm( y, sk->g, sk->x, sk->p ); - rc = !mpi_cmp( y, sk->y ); - mpi_free( y ); - return rc; + gcry_mpi_powm( y, sk->g, sk->x, sk->p ); + rc = !mpi_cmp( y, sk->y ); + mpi_free( y ); + return rc; } -/**************** - * Make a DSA signature from HASH and put it into r and s. +/* + Make a DSA signature from HASH and put it into r and s. */ - static void sign(gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t hash, DSA_secret_key *skey ) { - gcry_mpi_t k; - gcry_mpi_t kinv; - gcry_mpi_t tmp; - - /* select a random k with 0 < k < q */ - k = gen_k( skey->q ); - - /* r = (a^k mod p) mod q */ - gcry_mpi_powm( r, skey->g, k, skey->p ); - mpi_fdiv_r( r, r, skey->q ); - - /* kinv = k^(-1) mod q */ - kinv = mpi_alloc( mpi_get_nlimbs(k) ); - mpi_invm(kinv, k, skey->q ); - - /* s = (kinv * ( hash + x * r)) mod q */ - tmp = mpi_alloc( mpi_get_nlimbs(skey->p) ); - mpi_mul( tmp, skey->x, r ); - mpi_add( tmp, tmp, hash ); - mpi_mulm( s , kinv, tmp, skey->q ); - - mpi_free(k); - mpi_free(kinv); - mpi_free(tmp); + gcry_mpi_t k; + gcry_mpi_t kinv; + gcry_mpi_t tmp; + + /* Select a random k with 0 < k < q */ + k = gen_k( skey->q ); + + /* r = (a^k mod p) mod q */ + gcry_mpi_powm( r, skey->g, k, skey->p ); + mpi_fdiv_r( r, r, skey->q ); + + /* kinv = k^(-1) mod q */ + kinv = mpi_alloc( mpi_get_nlimbs(k) ); + mpi_invm(kinv, k, skey->q ); + + /* s = (kinv * ( hash + x * r)) mod q */ + tmp = mpi_alloc( mpi_get_nlimbs(skey->p) ); + mpi_mul( tmp, skey->x, r ); + mpi_add( tmp, tmp, hash ); + mpi_mulm( s , kinv, tmp, skey->q ); + + mpi_free(k); + mpi_free(kinv); + mpi_free(tmp); } -/**************** - * Returns true if the signature composed from R and S is valid. +/* + Returns true if the signature composed from R and S is valid. */ static int -verify(gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t hash, DSA_public_key *pkey ) +verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t hash, DSA_public_key *pkey ) { - int rc; - gcry_mpi_t w, u1, u2, v; - gcry_mpi_t base[3]; - gcry_mpi_t ex[3]; + int rc; + gcry_mpi_t w, u1, u2, v; + gcry_mpi_t base[3]; + gcry_mpi_t ex[3]; + if( !(mpi_cmp_ui( r, 0 ) > 0 && mpi_cmp( r, pkey->q ) < 0) ) + return 0; /* assertion 0 < r < q failed */ + if( !(mpi_cmp_ui( s, 0 ) > 0 && mpi_cmp( s, pkey->q ) < 0) ) + return 0; /* assertion 0 < s < q failed */ - if( !(mpi_cmp_ui( r, 0 ) > 0 && mpi_cmp( r, pkey->q ) < 0) ) - return 0; /* assertion 0 < r < q failed */ - if( !(mpi_cmp_ui( s, 0 ) > 0 && mpi_cmp( s, pkey->q ) < 0) ) - return 0; /* assertion 0 < s < q failed */ + w = mpi_alloc( mpi_get_nlimbs(pkey->q) ); + u1 = mpi_alloc( mpi_get_nlimbs(pkey->q) ); + u2 = mpi_alloc( mpi_get_nlimbs(pkey->q) ); + v = mpi_alloc( mpi_get_nlimbs(pkey->p) ); - w = mpi_alloc( mpi_get_nlimbs(pkey->q) ); - u1 = mpi_alloc( mpi_get_nlimbs(pkey->q) ); - u2 = mpi_alloc( mpi_get_nlimbs(pkey->q) ); - v = mpi_alloc( mpi_get_nlimbs(pkey->p) ); + /* w = s^(-1) mod q */ + mpi_invm( w, s, pkey->q ); - /* w = s^(-1) mod q */ - mpi_invm( w, s, pkey->q ); + /* u1 = (hash * w) mod q */ + mpi_mulm( u1, hash, w, pkey->q ); - /* u1 = (hash * w) mod q */ - mpi_mulm( u1, hash, w, pkey->q ); + /* u2 = r * w mod q */ + mpi_mulm( u2, r, w, pkey->q ); - /* u2 = r * w mod q */ - mpi_mulm( u2, r, w, pkey->q ); + /* v = g^u1 * y^u2 mod p mod q */ + base[0] = pkey->g; ex[0] = u1; + base[1] = pkey->y; ex[1] = u2; + base[2] = NULL; ex[2] = NULL; + mpi_mulpowm( v, base, ex, pkey->p ); + mpi_fdiv_r( v, v, pkey->q ); - /* v = g^u1 * y^u2 mod p mod q */ - base[0] = pkey->g; ex[0] = u1; - base[1] = pkey->y; ex[1] = u2; - base[2] = NULL; ex[2] = NULL; - mpi_mulpowm( v, base, ex, pkey->p ); - mpi_fdiv_r( v, v, pkey->q ); + rc = !mpi_cmp( v, r ); - rc = !mpi_cmp( v, r ); + mpi_free(w); + mpi_free(u1); + mpi_free(u2); + mpi_free(v); - mpi_free(w); - mpi_free(u1); - mpi_free(u2); - mpi_free(v); - return rc; + return rc; } @@ -469,3 +483,4 @@ gcry_pk_spec_t _gcry_pubkey_spec_dsa = _gcry_dsa_verify, _gcry_dsa_get_nbits, }; + diff --git a/cipher/elgamal.c b/cipher/elgamal.c index 27903f95..e62b1e51 100644 --- a/cipher/elgamal.c +++ b/cipher/elgamal.c @@ -51,17 +51,22 @@ static void test_keys (ELG_secret_key *sk, unsigned nbits); static gcry_mpi_t gen_k (gcry_mpi_t p, int small_k); static void generate (ELG_secret_key *sk, unsigned nbits, gcry_mpi_t **factors); static int check_secret_key (ELG_secret_key *sk); -static void do_encrypt (gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey); -static void decrypt (gcry_mpi_t output, gcry_mpi_t a, gcry_mpi_t b, ELG_secret_key *skey); -static void sign (gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_secret_key *skey); -static int verify (gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey); +static void do_encrypt (gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, + ELG_public_key *pkey); +static void decrypt (gcry_mpi_t output, gcry_mpi_t a, gcry_mpi_t b, + ELG_secret_key *skey); +static void sign (gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, + ELG_secret_key *skey); +static int verify (gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, + ELG_public_key *pkey); static void (*progress_cb) (void *, const char *, int, int, int); static void *progress_cb_data; void -_gcry_register_pk_elg_progress (void (*cb) (void *, const char *, int, int, int), +_gcry_register_pk_elg_progress (void (*cb) (void *, const char *, + int, int, int), void *cb_data) { progress_cb = cb; @@ -84,67 +89,68 @@ progress (int c) static unsigned int wiener_map( unsigned int n ) { - static struct { unsigned int p_n, q_n; } t[] = - { /* p q attack cost */ - { 512, 119 }, /* 9 x 10^17 */ - { 768, 145 }, /* 6 x 10^21 */ - { 1024, 165 }, /* 7 x 10^24 */ - { 1280, 183 }, /* 3 x 10^27 */ - { 1536, 198 }, /* 7 x 10^29 */ - { 1792, 212 }, /* 9 x 10^31 */ - { 2048, 225 }, /* 8 x 10^33 */ - { 2304, 237 }, /* 5 x 10^35 */ - { 2560, 249 }, /* 3 x 10^37 */ - { 2816, 259 }, /* 1 x 10^39 */ - { 3072, 269 }, /* 3 x 10^40 */ - { 3328, 279 }, /* 8 x 10^41 */ - { 3584, 288 }, /* 2 x 10^43 */ - { 3840, 296 }, /* 4 x 10^44 */ - { 4096, 305 }, /* 7 x 10^45 */ - { 4352, 313 }, /* 1 x 10^47 */ - { 4608, 320 }, /* 2 x 10^48 */ - { 4864, 328 }, /* 2 x 10^49 */ - { 5120, 335 }, /* 3 x 10^50 */ - { 0, 0 } + static struct { unsigned int p_n, q_n; } t[] = + { /* p q attack cost */ + { 512, 119 }, /* 9 x 10^17 */ + { 768, 145 }, /* 6 x 10^21 */ + { 1024, 165 }, /* 7 x 10^24 */ + { 1280, 183 }, /* 3 x 10^27 */ + { 1536, 198 }, /* 7 x 10^29 */ + { 1792, 212 }, /* 9 x 10^31 */ + { 2048, 225 }, /* 8 x 10^33 */ + { 2304, 237 }, /* 5 x 10^35 */ + { 2560, 249 }, /* 3 x 10^37 */ + { 2816, 259 }, /* 1 x 10^39 */ + { 3072, 269 }, /* 3 x 10^40 */ + { 3328, 279 }, /* 8 x 10^41 */ + { 3584, 288 }, /* 2 x 10^43 */ + { 3840, 296 }, /* 4 x 10^44 */ + { 4096, 305 }, /* 7 x 10^45 */ + { 4352, 313 }, /* 1 x 10^47 */ + { 4608, 320 }, /* 2 x 10^48 */ + { 4864, 328 }, /* 2 x 10^49 */ + { 5120, 335 }, /* 3 x 10^50 */ + { 0, 0 } }; - int i; + int i; - for(i=0; t[i].p_n; i++ ) { - if( n <= t[i].p_n ) - return t[i].q_n; + for(i=0; t[i].p_n; i++ ) + { + if( n <= t[i].p_n ) + return t[i].q_n; } - /* not in table - use some arbitrary high number ;-) */ - return n / 8 + 200; + /* Not in table - use an arbitrary high number. */ + return n / 8 + 200; } static void test_keys( ELG_secret_key *sk, unsigned nbits ) { - ELG_public_key pk; - gcry_mpi_t test = gcry_mpi_new ( 0 ); - gcry_mpi_t out1_a = gcry_mpi_new ( nbits ); - gcry_mpi_t out1_b = gcry_mpi_new ( nbits ); - gcry_mpi_t out2 = gcry_mpi_new ( nbits ); - - pk.p = sk->p; - pk.g = sk->g; - pk.y = sk->y; - - gcry_mpi_randomize( test, nbits, GCRY_WEAK_RANDOM ); - - do_encrypt( out1_a, out1_b, test, &pk ); - decrypt( out2, out1_a, out1_b, sk ); - if( mpi_cmp( test, out2 ) ) - log_fatal("ElGamal operation: encrypt, decrypt failed\n"); - - sign( out1_a, out1_b, test, sk ); - if( !verify( out1_a, out1_b, test, &pk ) ) - log_fatal("ElGamal operation: sign, verify failed\n"); - - gcry_mpi_release ( test ); - gcry_mpi_release ( out1_a ); - gcry_mpi_release ( out1_b ); - gcry_mpi_release ( out2 ); + ELG_public_key pk; + gcry_mpi_t test = gcry_mpi_new ( 0 ); + gcry_mpi_t out1_a = gcry_mpi_new ( nbits ); + gcry_mpi_t out1_b = gcry_mpi_new ( nbits ); + gcry_mpi_t out2 = gcry_mpi_new ( nbits ); + + pk.p = sk->p; + pk.g = sk->g; + pk.y = sk->y; + + gcry_mpi_randomize( test, nbits, GCRY_WEAK_RANDOM ); + + do_encrypt( out1_a, out1_b, test, &pk ); + decrypt( out2, out1_a, out1_b, sk ); + if( mpi_cmp( test, out2 ) ) + log_fatal("ElGamal operation: encrypt, decrypt failed\n"); + + sign( out1_a, out1_b, test, sk ); + if( !verify( out1_a, out1_b, test, &pk ) ) + log_fatal("ElGamal operation: sign, verify failed\n"); + + gcry_mpi_release ( test ); + gcry_mpi_release ( out1_a ); + gcry_mpi_release ( out1_b ); + gcry_mpi_release ( out2 ); } @@ -156,77 +162,79 @@ test_keys( ELG_secret_key *sk, unsigned nbits ) static gcry_mpi_t gen_k( gcry_mpi_t p, int small_k ) { - gcry_mpi_t k = mpi_alloc_secure( 0 ); - gcry_mpi_t temp = mpi_alloc( mpi_get_nlimbs(p) ); - gcry_mpi_t p_1 = mpi_copy(p); - unsigned int orig_nbits = mpi_get_nbits(p); - unsigned int nbits, nbytes; - char *rndbuf = NULL; - - if (small_k) - { - /* Using a k much lesser than p is sufficient for encryption and - * it greatly improves the encryption performance. We use - * Wiener's table and add a large safety margin. - */ - nbits = wiener_map( orig_nbits ) * 3 / 2; - if( nbits >= orig_nbits ) - BUG(); - } - else - nbits = orig_nbits; - - - nbytes = (nbits+7)/8; - if( DBG_CIPHER ) - log_debug("choosing a random k "); - mpi_sub_ui( p_1, p, 1); - for(;;) { - if( !rndbuf || nbits < 32 ) { - gcry_free(rndbuf); - rndbuf = gcry_random_bytes_secure( nbytes, GCRY_STRONG_RANDOM ); - } - else { /* change only some of the higher bits */ - /* we could improve this by directly requesting more memory - * at the first call to get_random_bytes() and use this the here - * maybe it is easier to do this directly in random.c - * Anyway, it is highly inlikely that we will ever reach this code - */ - char *pp = gcry_random_bytes_secure( 4, GCRY_STRONG_RANDOM ); - memcpy( rndbuf, pp, 4 ); - gcry_free(pp); + gcry_mpi_t k = mpi_alloc_secure( 0 ); + gcry_mpi_t temp = mpi_alloc( mpi_get_nlimbs(p) ); + gcry_mpi_t p_1 = mpi_copy(p); + unsigned int orig_nbits = mpi_get_nbits(p); + unsigned int nbits, nbytes; + char *rndbuf = NULL; + + if (small_k) + { + /* Using a k much lesser than p is sufficient for encryption and + * it greatly improves the encryption performance. We use + * Wiener's table and add a large safety margin. */ + nbits = wiener_map( orig_nbits ) * 3 / 2; + if( nbits >= orig_nbits ) + BUG(); + } + else + nbits = orig_nbits; + + + nbytes = (nbits+7)/8; + if( DBG_CIPHER ) + log_debug("choosing a random k "); + mpi_sub_ui( p_1, p, 1); + for(;;) + { + if( !rndbuf || nbits < 32 ) + { + gcry_free(rndbuf); + rndbuf = gcry_random_bytes_secure( nbytes, GCRY_STRONG_RANDOM ); + } + else + { + /* Change only some of the higher bits. We could improve + this by directly requesting more memory at the first call + to get_random_bytes() and use this the here maybe it is + easier to do this directly in random.c Anyway, it is + highly inlikely that we will ever reach this code. */ + char *pp = gcry_random_bytes_secure( 4, GCRY_STRONG_RANDOM ); + memcpy( rndbuf, pp, 4 ); + gcry_free(pp); } - _gcry_mpi_set_buffer( k, rndbuf, nbytes, 0 ); - - for(;;) { - /* Hmm, actually we don't need this step here - * because we use k much smaller than p - we do it anyway - * just in case the keep on adding a one to k ;) */ - if( !(mpi_cmp( k, p_1 ) < 0) ) { /* check: k < (p-1) */ - if( DBG_CIPHER ) - progress('+'); - break; /* no */ - } - if( !(mpi_cmp_ui( k, 0 ) > 0) ) { /* check: k > 0 */ - if( DBG_CIPHER ) - progress('-'); - break; /* no */ - } - if( gcry_mpi_gcd( temp, k, p_1 ) ) - goto found; /* okay, k is relatively prime to (p-1) */ - mpi_add_ui( k, k, 1 ); - if( DBG_CIPHER ) - progress('.'); + _gcry_mpi_set_buffer( k, rndbuf, nbytes, 0 ); + + for(;;) + { + if( !(mpi_cmp( k, p_1 ) < 0) ) /* check: k < (p-1) */ + { + if( DBG_CIPHER ) + progress('+'); + break; /* no */ + } + if( !(mpi_cmp_ui( k, 0 ) > 0) ) /* check: k > 0 */ + { + if( DBG_CIPHER ) + progress('-'); + break; /* no */ + } + if (gcry_mpi_gcd( temp, k, p_1 )) + goto found; /* okay, k is relative prime to (p-1) */ + mpi_add_ui( k, k, 1 ); + if( DBG_CIPHER ) + progress('.'); } } - found: - gcry_free(rndbuf); - if( DBG_CIPHER ) - progress('\n'); - mpi_free(p_1); - mpi_free(temp); - - return k; + found: + gcry_free(rndbuf); + if( DBG_CIPHER ) + progress('\n'); + mpi_free(p_1); + mpi_free(temp); + + return k; } /**************** @@ -235,93 +243,100 @@ gen_k( gcry_mpi_t p, int small_k ) * and an array with n-1 factors of (p-1) */ static void -generate( ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t **ret_factors ) +generate ( ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t **ret_factors ) { - gcry_mpi_t p; /* the prime */ - gcry_mpi_t p_min1; - gcry_mpi_t g; - gcry_mpi_t x; /* the secret exponent */ - gcry_mpi_t y; - gcry_mpi_t temp; - unsigned int qbits; - unsigned int xbits; - byte *rndbuf; - - p_min1 = gcry_mpi_new ( nbits ); - temp = gcry_mpi_new( nbits ); - qbits = wiener_map( nbits ); - if( qbits & 1 ) /* better have a even one */ - qbits++; - g = mpi_alloc(1); - p = _gcry_generate_elg_prime( 0, nbits, qbits, g, ret_factors ); - mpi_sub_ui(p_min1, p, 1); - - - /* select a random number which has these properties: - * 0 < x < p-1 - * This must be a very good random number because this is the - * secret part. The prime is public and may be shared anyway, - * so a random generator level of 1 is used for the prime. - * - * I don't see a reason to have a x of about the same size - * as the p. It should be sufficient to have one about the size - * of q or the later used k plus a large safety margin. Decryption - * will be much faster with such an x. - */ - xbits = qbits * 3 / 2; - if( xbits >= nbits ) - BUG(); - x = gcry_mpi_snew ( xbits ); - if( DBG_CIPHER ) - log_debug("choosing a random x of size %u", xbits ); - rndbuf = NULL; - do { - if( DBG_CIPHER ) - progress('.'); - if( rndbuf ) { /* change only some of the higher bits */ - if( xbits < 16 ) {/* should never happen ... */ - gcry_free(rndbuf); - rndbuf = gcry_random_bytes_secure( (xbits+7)/8, - GCRY_VERY_STRONG_RANDOM ); - } - else { - char *r = gcry_random_bytes_secure( 2, - GCRY_VERY_STRONG_RANDOM ); - memcpy(rndbuf, r, 2 ); - gcry_free(r); - } + gcry_mpi_t p; /* the prime */ + gcry_mpi_t p_min1; + gcry_mpi_t g; + gcry_mpi_t x; /* the secret exponent */ + gcry_mpi_t y; + gcry_mpi_t temp; + unsigned int qbits; + unsigned int xbits; + byte *rndbuf; + + p_min1 = gcry_mpi_new ( nbits ); + temp = gcry_mpi_new( nbits ); + qbits = wiener_map( nbits ); + if( qbits & 1 ) /* better have a even one */ + qbits++; + g = mpi_alloc(1); + p = _gcry_generate_elg_prime( 0, nbits, qbits, g, ret_factors ); + mpi_sub_ui(p_min1, p, 1); + + + /* Select a random number which has these properties: + * 0 < x < p-1 + * This must be a very good random number because this is the + * secret part. The prime is public and may be shared anyway, + * so a random generator level of 1 is used for the prime. + * + * I don't see a reason to have a x of about the same size + * as the p. It should be sufficient to have one about the size + * of q or the later used k plus a large safety margin. Decryption + * will be much faster with such an x. + */ + xbits = qbits * 3 / 2; + if( xbits >= nbits ) + BUG(); + x = gcry_mpi_snew ( xbits ); + if( DBG_CIPHER ) + log_debug("choosing a random x of size %u", xbits ); + rndbuf = NULL; + do + { + if( DBG_CIPHER ) + progress('.'); + if( rndbuf ) + { /* Change only some of the higher bits */ + if( xbits < 16 ) /* should never happen ... */ + { + gcry_free(rndbuf); + rndbuf = gcry_random_bytes_secure( (xbits+7)/8, + GCRY_VERY_STRONG_RANDOM ); + } + else + { + char *r = gcry_random_bytes_secure( 2, + GCRY_VERY_STRONG_RANDOM ); + memcpy(rndbuf, r, 2 ); + gcry_free(r); + } } - else { - rndbuf = gcry_random_bytes_secure( (xbits+7)/8, - GCRY_VERY_STRONG_RANDOM ); + else + { + rndbuf = gcry_random_bytes_secure( (xbits+7)/8, + GCRY_VERY_STRONG_RANDOM ); } - _gcry_mpi_set_buffer( x, rndbuf, (xbits+7)/8, 0 ); - mpi_clear_highbit( x, xbits+1 ); - } while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, p_min1 )<0 ) ); - gcry_free(rndbuf); - - y = gcry_mpi_new (nbits); - gcry_mpi_powm( y, g, x, p ); - - if( DBG_CIPHER ) { - progress('\n'); - log_mpidump("elg p= ", p ); - log_mpidump("elg g= ", g ); - log_mpidump("elg y= ", y ); - log_mpidump("elg x= ", x ); + _gcry_mpi_set_buffer( x, rndbuf, (xbits+7)/8, 0 ); + mpi_clear_highbit( x, xbits+1 ); + } + while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, p_min1 )<0 ) ); + gcry_free(rndbuf); + + y = gcry_mpi_new (nbits); + gcry_mpi_powm( y, g, x, p ); + + if( DBG_CIPHER ) + { + progress('\n'); + log_mpidump("elg p= ", p ); + log_mpidump("elg g= ", g ); + log_mpidump("elg y= ", y ); + log_mpidump("elg x= ", x ); } - /* copy the stuff to the key structures */ - sk->p = p; - sk->g = g; - sk->y = y; - sk->x = x; + /* Copy the stuff to the key structures */ + sk->p = p; + sk->g = g; + sk->y = y; + sk->x = x; - /* now we can test our keys (this should never fail!) */ - test_keys( sk, nbits - 64 ); + /* Now we can test our keys (this should never fail!) */ + test_keys( sk, nbits - 64 ); - gcry_mpi_release ( p_min1 ); - gcry_mpi_release ( temp ); + gcry_mpi_release ( p_min1 ); + gcry_mpi_release ( temp ); } @@ -332,46 +347,47 @@ generate( ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t **ret_factors ) static int check_secret_key( ELG_secret_key *sk ) { - int rc; - gcry_mpi_t y = mpi_alloc( mpi_get_nlimbs(sk->y) ); + int rc; + gcry_mpi_t y = mpi_alloc( mpi_get_nlimbs(sk->y) ); - gcry_mpi_powm( y, sk->g, sk->x, sk->p ); - rc = !mpi_cmp( y, sk->y ); - mpi_free( y ); - return rc; + gcry_mpi_powm( y, sk->g, sk->x, sk->p ); + rc = !mpi_cmp( y, sk->y ); + mpi_free( y ); + return rc; } static void do_encrypt(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey ) { - gcry_mpi_t k; - - /* Note: maybe we should change the interface, so that it - * is possible to check that input is < p and return an - * error code. - */ - - k = gen_k( pkey->p, 1 ); - gcry_mpi_powm( a, pkey->g, k, pkey->p ); - /* b = (y^k * input) mod p - * = ((y^k mod p) * (input mod p)) mod p - * and because input is < p - * = ((y^k mod p) * input) mod p - */ - gcry_mpi_powm( b, pkey->y, k, pkey->p ); - gcry_mpi_mulm( b, b, input, pkey->p ); + gcry_mpi_t k; + + /* Note: maybe we should change the interface, so that it + * is possible to check that input is < p and return an + * error code. + */ + + k = gen_k( pkey->p, 1 ); + gcry_mpi_powm( a, pkey->g, k, pkey->p ); + /* b = (y^k * input) mod p + * = ((y^k mod p) * (input mod p)) mod p + * and because input is < p + * = ((y^k mod p) * input) mod p + */ + gcry_mpi_powm( b, pkey->y, k, pkey->p ); + gcry_mpi_mulm( b, b, input, pkey->p ); #if 0 - if( DBG_CIPHER ) { - log_mpidump("elg encrypted y= ", pkey->y); - log_mpidump("elg encrypted p= ", pkey->p); - log_mpidump("elg encrypted k= ", k); - log_mpidump("elg encrypted M= ", input); - log_mpidump("elg encrypted a= ", a); - log_mpidump("elg encrypted b= ", b); + if( DBG_CIPHER ) + { + log_mpidump("elg encrypted y= ", pkey->y); + log_mpidump("elg encrypted p= ", pkey->p); + log_mpidump("elg encrypted k= ", k); + log_mpidump("elg encrypted M= ", input); + log_mpidump("elg encrypted a= ", a); + log_mpidump("elg encrypted b= ", b); } #endif - mpi_free(k); + mpi_free(k); } @@ -380,22 +396,23 @@ do_encrypt(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey ) static void decrypt(gcry_mpi_t output, gcry_mpi_t a, gcry_mpi_t b, ELG_secret_key *skey ) { - gcry_mpi_t t1 = mpi_alloc_secure( mpi_get_nlimbs( skey->p ) ); + gcry_mpi_t t1 = mpi_alloc_secure( mpi_get_nlimbs( skey->p ) ); - /* output = b/(a^x) mod p */ - gcry_mpi_powm( t1, a, skey->x, skey->p ); - mpi_invm( t1, t1, skey->p ); - mpi_mulm( output, b, t1, skey->p ); + /* output = b/(a^x) mod p */ + gcry_mpi_powm( t1, a, skey->x, skey->p ); + mpi_invm( t1, t1, skey->p ); + mpi_mulm( output, b, t1, skey->p ); #if 0 - if( DBG_CIPHER ) { - log_mpidump("elg decrypted x= ", skey->x); - log_mpidump("elg decrypted p= ", skey->p); - log_mpidump("elg decrypted a= ", a); - log_mpidump("elg decrypted b= ", b); - log_mpidump("elg decrypted M= ", output); + if( DBG_CIPHER ) + { + log_mpidump("elg decrypted x= ", skey->x); + log_mpidump("elg decrypted p= ", skey->p); + log_mpidump("elg decrypted a= ", a); + log_mpidump("elg decrypted b= ", b); + log_mpidump("elg decrypted M= ", output); } #endif - mpi_free(t1); + mpi_free(t1); } @@ -426,7 +443,8 @@ sign(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_secret_key *skey ) mpi_mulm(b, t, inv, p_1 ); #if 0 - if( DBG_CIPHER ) { + if( DBG_CIPHER ) + { log_mpidump("elg sign p= ", skey->p); log_mpidump("elg sign g= ", skey->g); log_mpidump("elg sign y= ", skey->y); @@ -435,7 +453,7 @@ sign(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_secret_key *skey ) log_mpidump("elg sign M= ", input); log_mpidump("elg sign a= ", a); log_mpidump("elg sign b= ", b); - } + } #endif mpi_free(k); mpi_free(t); @@ -450,54 +468,54 @@ sign(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_secret_key *skey ) static int verify(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey ) { - int rc; - gcry_mpi_t t1; - gcry_mpi_t t2; - gcry_mpi_t base[4]; - gcry_mpi_t ex[4]; + int rc; + gcry_mpi_t t1; + gcry_mpi_t t2; + gcry_mpi_t base[4]; + gcry_mpi_t ex[4]; - if( !(mpi_cmp_ui( a, 0 ) > 0 && mpi_cmp( a, pkey->p ) < 0) ) - return 0; /* assertion 0 < a < p failed */ + if( !(mpi_cmp_ui( a, 0 ) > 0 && mpi_cmp( a, pkey->p ) < 0) ) + return 0; /* assertion 0 < a < p failed */ - t1 = mpi_alloc( mpi_get_nlimbs(a) ); - t2 = mpi_alloc( mpi_get_nlimbs(a) ); + t1 = mpi_alloc( mpi_get_nlimbs(a) ); + t2 = mpi_alloc( mpi_get_nlimbs(a) ); #if 0 - /* t1 = (y^a mod p) * (a^b mod p) mod p */ - gcry_mpi_powm( t1, pkey->y, a, pkey->p ); - gcry_mpi_powm( t2, a, b, pkey->p ); - mpi_mulm( t1, t1, t2, pkey->p ); + /* t1 = (y^a mod p) * (a^b mod p) mod p */ + gcry_mpi_powm( t1, pkey->y, a, pkey->p ); + gcry_mpi_powm( t2, a, b, pkey->p ); + mpi_mulm( t1, t1, t2, pkey->p ); - /* t2 = g ^ input mod p */ - gcry_mpi_powm( t2, pkey->g, input, pkey->p ); + /* t2 = g ^ input mod p */ + gcry_mpi_powm( t2, pkey->g, input, pkey->p ); - rc = !mpi_cmp( t1, t2 ); + rc = !mpi_cmp( t1, t2 ); #elif 0 - /* t1 = (y^a mod p) * (a^b mod p) mod p */ - base[0] = pkey->y; ex[0] = a; - base[1] = a; ex[1] = b; - base[2] = NULL; ex[2] = NULL; - mpi_mulpowm( t1, base, ex, pkey->p ); + /* t1 = (y^a mod p) * (a^b mod p) mod p */ + base[0] = pkey->y; ex[0] = a; + base[1] = a; ex[1] = b; + base[2] = NULL; ex[2] = NULL; + mpi_mulpowm( t1, base, ex, pkey->p ); - /* t2 = g ^ input mod p */ - gcry_mpi_powm( t2, pkey->g, input, pkey->p ); + /* t2 = g ^ input mod p */ + gcry_mpi_powm( t2, pkey->g, input, pkey->p ); - rc = !mpi_cmp( t1, t2 ); + rc = !mpi_cmp( t1, t2 ); #else - /* t1 = g ^ - input * y ^ a * a ^ b mod p */ - mpi_invm(t2, pkey->g, pkey->p ); - base[0] = t2 ; ex[0] = input; - base[1] = pkey->y; ex[1] = a; - base[2] = a; ex[2] = b; - base[3] = NULL; ex[3] = NULL; - mpi_mulpowm( t1, base, ex, pkey->p ); - rc = !mpi_cmp_ui( t1, 1 ); + /* t1 = g ^ - input * y ^ a * a ^ b mod p */ + mpi_invm(t2, pkey->g, pkey->p ); + base[0] = t2 ; ex[0] = input; + base[1] = pkey->y; ex[1] = a; + base[2] = a; ex[2] = b; + base[3] = NULL; ex[3] = NULL; + mpi_mulpowm( t1, base, ex, pkey->p ); + rc = !mpi_cmp_ui( t1, 1 ); #endif - mpi_free(t1); - mpi_free(t2); - return rc; + mpi_free(t1); + mpi_free(t2); + return rc; } /********************************************* @@ -544,7 +562,8 @@ _gcry_elg_check_secret_key (int algo, gcry_mpi_t *skey) gcry_err_code_t -_gcry_elg_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *pkey, int flags) +_gcry_elg_encrypt (int algo, gcry_mpi_t *resarr, + gcry_mpi_t data, gcry_mpi_t *pkey, int flags) { gcry_err_code_t err = GPG_ERR_NO_ERROR; ELG_public_key pk; @@ -565,7 +584,8 @@ _gcry_elg_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *pk gcry_err_code_t -_gcry_elg_decrypt (int algo, gcry_mpi_t *result, gcry_mpi_t *data, gcry_mpi_t *skey, int flags) +_gcry_elg_decrypt (int algo, gcry_mpi_t *result, + gcry_mpi_t *data, gcry_mpi_t *skey, int flags) { gcry_err_code_t err = GPG_ERR_NO_ERROR; ELG_secret_key sk; |