diff options
Diffstat (limited to 'g10')
-rw-r--r-- | g10/ChangeLog | 11 | ||||
-rw-r--r-- | g10/build-packet.c | 3 | ||||
-rw-r--r-- | g10/cipher.c | 12 | ||||
-rw-r--r-- | g10/encr-data.c | 44 | ||||
-rw-r--r-- | g10/filter.h | 1 | ||||
-rw-r--r-- | g10/passphrase.c | 13 | ||||
-rw-r--r-- | g10/pubkey-enc.c | 3 | ||||
-rw-r--r-- | g10/seckey-cert.c | 80 | ||||
-rw-r--r-- | g10/seskey.c | 1 |
9 files changed, 145 insertions, 23 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog index b82ceae28..e16f15550 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,14 @@ +Sat Apr 4 20:07:01 1998 Werner Koch ([email protected]) + + * cipher.c (cipher_filter): Support for CAST5 + * encr-data.c (decode_filter): Ditto. + (decrypt_data): Ditto. + * seskey.c (make_session_key): Ditto. + * seckey-cert.c (check_elg, check_dsa): Ditto, + (protect_secret_key): Ditto. + * pubkey-enc.c (get_session_key): Ditto. + * passphrase.c (hash_passphrase): Ditto. + Thu Apr 2 20:22:35 1998 Werner Koch ([email protected]) * gpgd.c: New diff --git a/g10/build-packet.c b/g10/build-packet.c index 85278af1c..4d0a7d69f 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -289,7 +289,8 @@ do_secret_cert( IOBUF out, int ctb, PKT_secret_cert *skc ) mpi_write(a, skc->d.rsa.rsa_n ); mpi_write(a, skc->d.rsa.rsa_e ); if( skc->is_protected ) { - assert( skc->protect.algo == CIPHER_ALGO_BLOWFISH ); + assert( skc->protect.algo == CIPHER_ALGO_BLOWFISH + || skc->protect.algo == CIPHER_ALGO_CAST ); iobuf_put(a, skc->protect.algo ); iobuf_write(a, skc->protect.iv, 8 ); } diff --git a/g10/cipher.c b/g10/cipher.c index 52da03b58..8e6c91aa9 100644 --- a/g10/cipher.c +++ b/g10/cipher.c @@ -74,6 +74,13 @@ cipher_filter( void *opaque, int control, blowfish_setiv( cfx->bf_ctx, NULL ); blowfish_encode_cfb( cfx->bf_ctx, temp, temp, 10); } + else if( cfx->dek->algo == CIPHER_ALGO_CAST ) { + cfx->cast5_ctx = m_alloc_secure( sizeof *cfx->cast5_ctx ); + cast5_setkey( cfx->cast5_ctx, cfx->dek->key, cfx->dek->keylen ); + cast5_setiv( cfx->cast5_ctx, NULL ); + cast5_encode_cfb( cfx->cast5_ctx, temp, temp, 10); + cast5_sync_cfb( cfx->cast5_ctx ); + } else log_bug("no cipher algo %d\n", cfx->dek->algo); @@ -84,6 +91,9 @@ cipher_filter( void *opaque, int control, if( cfx->dek->algo == CIPHER_ALGO_BLOWFISH || cfx->dek->algo == CIPHER_ALGO_BLOWFISH128 ) blowfish_encode_cfb( cfx->bf_ctx, buf, buf, size); + else if( cfx->dek->algo == CIPHER_ALGO_CAST ) + cast5_encode_cfb( cfx->cast5_ctx, buf, buf, size); + if( iobuf_write( a, buf, size ) ) rc = G10ERR_WRITE_FILE; } @@ -91,6 +101,8 @@ cipher_filter( void *opaque, int control, if( cfx->dek->algo == CIPHER_ALGO_BLOWFISH || cfx->dek->algo == CIPHER_ALGO_BLOWFISH128 ) m_free(cfx->bf_ctx); + else if( cfx->dek->algo == CIPHER_ALGO_CAST ) + m_free(cfx->cast5_ctx); } else if( control == IOBUFCTRL_DESC ) { *(char**)buf = "cipher_filter"; diff --git a/g10/encr-data.c b/g10/encr-data.c index a1b4be0e9..4f8aa897d 100644 --- a/g10/encr-data.c +++ b/g10/encr-data.c @@ -28,13 +28,16 @@ #include "packet.h" #include "mpi.h" #include "cipher.h" +#include "options.h" static int decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len); typedef struct { + int is_cast5; BLOWFISH_context *bf_ctx; + CAST5_context *cast5_ctx; } decode_filter_ctx_t; @@ -50,16 +53,32 @@ decrypt_data( PKT_encrypted *ed, DEK *dek ) int c, i; byte temp[16]; - + if( opt.verbose ) { + const char *s = cipher_algo_to_string( dek->algo ); + if( s ) + log_info("%s encrypted data\n", s ); + else + log_info("encrypted with unknown algorithm %d\n", dek->algo ); + } if( dek->algo != CIPHER_ALGO_BLOWFISH - && dek->algo != CIPHER_ALGO_BLOWFISH128 ) + && dek->algo != CIPHER_ALGO_BLOWFISH128 + && dek->algo != CIPHER_ALGO_CAST ) return G10ERR_CIPHER_ALGO; if( ed->len && ed->len < 10 ) log_bug("Nanu\n"); /* oops: found a bug */ - dfx.bf_ctx = m_alloc_secure( sizeof *dfx.bf_ctx ); - blowfish_setkey( dfx.bf_ctx, dek->key, dek->keylen ); - blowfish_setiv( dfx.bf_ctx, NULL ); + if( dek->algo == CIPHER_ALGO_CAST ) { + dfx.is_cast5 = 1; + dfx.cast5_ctx = m_alloc_secure( sizeof *dfx.cast5_ctx ); + cast5_setkey( dfx.cast5_ctx, dek->key, dek->keylen ); + cast5_setiv( dfx.cast5_ctx, NULL ); + } + else { + dfx.is_cast5 = 0; + dfx.bf_ctx = m_alloc_secure( sizeof *dfx.bf_ctx ); + blowfish_setkey( dfx.bf_ctx, dek->key, dek->keylen ); + blowfish_setiv( dfx.bf_ctx, NULL ); + } if( ed->len ) { iobuf_set_limit( ed->buf, ed->len ); @@ -74,7 +93,12 @@ decrypt_data( PKT_encrypted *ed, DEK *dek ) else temp[i] = c; } - blowfish_decode_cfb( dfx.bf_ctx, temp, temp, 10); + if( dfx.is_cast5 ) { + cast5_decode_cfb( dfx.cast5_ctx, temp, temp, 10); + cast5_sync_cfb( dfx.cast5_ctx ); + } + else + blowfish_decode_cfb( dfx.bf_ctx, temp, temp, 10); p = temp; if( p[6] != p[8] || p[7] != p[9] ) { m_free(dfx.bf_ctx); @@ -108,8 +132,12 @@ decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len) buf[n] = c; } - if( n ) - blowfish_decode_cfb( fc->bf_ctx, buf, buf, n); + if( n ) { + if( fc->is_cast5 ) + cast5_decode_cfb( fc->cast5_ctx, buf, buf, n); + else + blowfish_decode_cfb( fc->bf_ctx, buf, buf, n); + } else rc = -1; /* eof */ *ret_len = n; diff --git a/g10/filter.h b/g10/filter.h index 2fa3b8c45..fac1e0e2b 100644 --- a/g10/filter.h +++ b/g10/filter.h @@ -61,6 +61,7 @@ typedef struct { DEK *dek; u32 datalen; BLOWFISH_context *bf_ctx; + CAST5_context *cast5_ctx; int header; } cipher_filter_context_t; diff --git a/g10/passphrase.c b/g10/passphrase.c index ee5d4105b..46ff83163 100644 --- a/g10/passphrase.c +++ b/g10/passphrase.c @@ -156,6 +156,19 @@ hash_passphrase( DEK *dek, char *pw, byte *salt ) memcpy( dek->key, md_read(md,0), dek->keylen ); md_close(md); } + else if( dek->algo == CIPHER_ALGO_CAST ) { + MD_HANDLE md; + + md = md_open(DIGEST_ALGO_SHA1, 1); + if( salt ) + md_write( md, salt, 8 ); + md_write( md, pw, strlen(pw) ); + md_final( md ); + /* use only the low 128 bits */ + dek->keylen = 16; + memcpy( dek->key, md_read(md,0), dek->keylen ); + md_close(md); + } else rc = G10ERR_UNSUPPORTED; return rc; diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index 8ffa6483c..f19af2189 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -135,13 +135,16 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek ) { rc = G10ERR_WRONG_SECKEY; goto leave; } break; case CIPHER_ALGO_BLOWFISH128: + case CIPHER_ALGO_CAST: if( dek->keylen != 16 ) { rc = G10ERR_WRONG_SECKEY; goto leave; } break; + #if 0 case CIPHER_ALGO_CAST: if( dek->keylen < 5 || dek->keylen > 16 ) { rc = G10ERR_WRONG_SECKEY; goto leave; } break; + #endif default: dek->algo = 0; rc = G10ERR_CIPHER_ALGO; diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c index 49870dcd9..dada0fd20 100644 --- a/g10/seckey-cert.c +++ b/g10/seckey-cert.c @@ -31,7 +31,10 @@ #include "cipher.h" #if BLOWFISH_BLOCKSIZE != 8 - #error unsupportted blocksize + #error unsupported blocksize +#endif +#if CAST5_BLOCKSIZE != 8 + #error unsupported blocksize #endif static u16 @@ -71,10 +74,12 @@ check_elg( PKT_secret_cert *cert ) DEK *dek = NULL; MPI test_x; BLOWFISH_context *blowfish_ctx=NULL; + CAST5_context *cast5_ctx=NULL; switch( cert->protect.algo ) { case CIPHER_ALGO_NONE: BUG(); break; case CIPHER_ALGO_BLOWFISH: + case CIPHER_ALGO_CAST: keyid_from_skc( cert, keyid ); if( cert->protect.s2k == 1 || cert->protect.s2k == 3 ) dek = get_passphrase_hash( keyid, NULL, @@ -82,23 +87,41 @@ check_elg( PKT_secret_cert *cert ) else dek = get_passphrase_hash( keyid, NULL, NULL ); - blowfish_ctx = m_alloc_secure( sizeof *blowfish_ctx ); - blowfish_setkey( blowfish_ctx, dek->key, dek->keylen ); + if( cert->protect.algo == CIPHER_ALGO_CAST ) + cast5_ctx = m_alloc_secure( sizeof *cast5_ctx ); + else + blowfish_ctx = m_alloc_secure( sizeof *blowfish_ctx ); + + if( blowfish_ctx ) { + blowfish_setkey( blowfish_ctx, dek->key, dek->keylen ); + blowfish_setiv( blowfish_ctx, NULL ); + } + else { + cast5_setkey( cast5_ctx, dek->key, dek->keylen ); + cast5_setiv( cast5_ctx, NULL ); + } m_free(dek); /* pw is in secure memory, so m_free() burns it */ - blowfish_setiv( blowfish_ctx, NULL ); memcpy(save_iv, cert->protect.iv, 8 ); - blowfish_decode_cfb( blowfish_ctx, cert->protect.iv, - cert->protect.iv, 8 ); + if( blowfish_ctx ) + blowfish_decode_cfb( blowfish_ctx, cert->protect.iv, + cert->protect.iv, 8 ); + else + cast5_decode_cfb( cast5_ctx, cert->protect.iv, + cert->protect.iv, 8 ); mpi_set_secure(cert->d.elg.x ); /*fixme: maybe it is better to set the buffer secure with a * new get_buffer_secure() function */ buffer = mpi_get_buffer( cert->d.elg.x, &nbytes, NULL ); csum = checksum_u16( nbytes*8 ); - blowfish_decode_cfb( blowfish_ctx, buffer, buffer, nbytes ); + if( blowfish_ctx ) + blowfish_decode_cfb( blowfish_ctx, buffer, buffer, nbytes ); + else + cast5_decode_cfb( cast5_ctx, buffer, buffer, nbytes ); csum += checksum( buffer, nbytes ); test_x = mpi_alloc_secure( mpi_get_nlimbs(cert->d.elg.x) ); mpi_set_buffer( test_x, buffer, nbytes, 0 ); m_free( buffer ); + m_free( cast5_ctx ); m_free( blowfish_ctx ); /* now let's see wether we have used the right passphrase */ if( csum != cert->csum ) { @@ -155,10 +178,12 @@ check_dsa( PKT_secret_cert *cert ) DEK *dek = NULL; MPI test_x; BLOWFISH_context *blowfish_ctx=NULL; + CAST5_context *cast5_ctx=NULL; switch( cert->protect.algo ) { case CIPHER_ALGO_NONE: BUG(); break; case CIPHER_ALGO_BLOWFISH: + case CIPHER_ALGO_CAST: keyid_from_skc( cert, keyid ); if( cert->protect.s2k == 1 || cert->protect.s2k == 3 ) dek = get_passphrase_hash( keyid, NULL, @@ -166,24 +191,38 @@ check_dsa( PKT_secret_cert *cert ) else dek = get_passphrase_hash( keyid, NULL, NULL ); - blowfish_ctx = m_alloc_secure( sizeof *blowfish_ctx ); - blowfish_setkey( blowfish_ctx, dek->key, dek->keylen ); + if( cert->protect.algo == CIPHER_ALGO_CAST ) { + cast5_ctx = m_alloc_secure( sizeof *cast5_ctx ); + cast5_setkey( cast5_ctx, dek->key, dek->keylen ); + cast5_setiv( cast5_ctx, NULL ); + } + else { + blowfish_ctx = m_alloc_secure( sizeof *blowfish_ctx ); + blowfish_setkey( blowfish_ctx, dek->key, dek->keylen ); + blowfish_setiv( blowfish_ctx, NULL ); + } m_free(dek); /* pw is in secure memory, so m_free() burns it */ - blowfish_setiv( blowfish_ctx, NULL ); memcpy(save_iv, cert->protect.iv, 8 ); - blowfish_decode_cfb( blowfish_ctx, - cert->protect.iv, - cert->protect.iv, 8 ); + if( blowfish_ctx ) + blowfish_decode_cfb( blowfish_ctx, cert->protect.iv, + cert->protect.iv, 8 ); + else + cast5_decode_cfb( cast5_ctx, cert->protect.iv, + cert->protect.iv, 8 ); mpi_set_secure(cert->d.dsa.x ); /*fixme: maybe it is better to set the buffer secure with a * new get_buffer_secure() function */ buffer = mpi_get_buffer( cert->d.dsa.x, &nbytes, NULL ); csum = checksum_u16( nbytes*8 ); - blowfish_decode_cfb( blowfish_ctx, buffer, buffer, nbytes ); + if( blowfish_ctx ) + blowfish_decode_cfb( blowfish_ctx, buffer, buffer, nbytes ); + else + cast5_decode_cfb( cast5_ctx, buffer, buffer, nbytes ); csum += checksum( buffer, nbytes ); test_x = mpi_alloc_secure( mpi_get_nlimbs(cert->d.dsa.x) ); mpi_set_buffer( test_x, buffer, nbytes, 0 ); m_free( buffer ); + m_free( cast5_ctx ); m_free( blowfish_ctx ); /* now let's see wether we have used the right passphrase */ if( csum != cert->csum ) { @@ -399,6 +438,7 @@ protect_secret_key( PKT_secret_cert *cert, DEK *dek ) if( !cert->is_protected ) { /* okay, apply the protection */ BLOWFISH_context *blowfish_ctx=NULL; + CAST5_context *cast5_ctx=NULL; switch( cert->protect.algo ) { case CIPHER_ALGO_NONE: BUG(); break; @@ -414,6 +454,18 @@ protect_secret_key( PKT_secret_cert *cert, DEK *dek ) m_free( blowfish_ctx ); break; + case CIPHER_ALGO_CAST: + cast5_ctx = m_alloc_secure( sizeof *cast5_ctx ); + cast5_setkey( cast5_ctx, dek->key, dek->keylen ); + cast5_setiv( cast5_ctx, NULL ); + cast5_encode_cfb( cast5_ctx, cert->protect.iv, + cert->protect.iv, 8 ); + if( !do_protect( (void (*)(void*,byte*,byte*,unsigned)) + &cast5_encode_cfb, cast5_ctx, cert ) ) + cert->is_protected = 1; + m_free( cast5_ctx ); + break; + default: rc = G10ERR_CIPHER_ALGO; /* unsupport protection algorithm */ break; diff --git a/g10/seskey.c b/g10/seskey.c index 314347a8b..b17302ea5 100644 --- a/g10/seskey.c +++ b/g10/seskey.c @@ -41,6 +41,7 @@ make_session_key( DEK *dek ) randomize_buffer( dek->key, dek->keylen, 1 ); break; case CIPHER_ALGO_BLOWFISH128: + case CIPHER_ALGO_CAST: dek->keylen = 16; randomize_buffer( dek->key, dek->keylen, 1 ); break; |