Changeset 343

Show
Ignore:
Timestamp:
01/30/06 16:10:43
Author:
ben
Message:

Working secret key decryption!

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • openpgpsdk/trunk/examples/packet-dump.c

    r342 r343  
    831831        print_hexdump("Salt",content->secret_key.salt, 
    832832                      sizeof content->secret_key.salt); 
    833         printf("Iterations: %d\n",content->secret_key.iterations); 
     833        printf("Octet count: %d\n",content->secret_key.octet_count); 
    834834        print_hexdump("IV",content->secret_key.iv, 
    835835                      ops_block_size(content->secret_key.algorithm)); 
     
    838838        if(content_->tag == OPS_PTAG_CT_ENCRYPTED_SECRET_KEY) 
    839839            break; 
    840  
    841         printf("Checksum: %04x\n",content->secret_key.checksum); 
    842840 
    843841        switch(content->secret_key.public_key.algorithm) 
     
    857855            assert(0); 
    858856            } 
     857 
     858        if(content->secret_key.s2k_usage == OPS_S2KU_ENCRYPTED_AND_HASHED) 
     859            print_hexdump("Checkhash",content->secret_key.checkhash, 
     860                          OPS_CHECKHASH_SIZE); 
     861        else 
     862            printf("Checksum: %04x\n",content->secret_key.checksum); 
     863 
    859864        break; 
    860865 
  • openpgpsdk/trunk/include/openpgpsdk/crypto.h

    r341 r343  
    99#include "packet-parse.h" 
    1010 
    11 #define OPS_MAX_HASH    64 
     11#define OPS_MAX_HASH_SIZE       64 
     12#define OPS_MIN_HASH_SIZE       16 
    1213 
    1314typedef void ops_hash_init_t(ops_hash_t *hash); 
     
    7677 
    7778unsigned ops_block_size(ops_symmetric_algorithm_t alg); 
     79unsigned ops_key_size(ops_symmetric_algorithm_t alg); 
    7880 
    7981int ops_decrypt_data(ops_region_t *region,ops_parse_info_t *parse_info); 
  • openpgpsdk/trunk/include/openpgpsdk/packet.h

    r341 r343  
    422422#define OPS_SALT_SIZE           8 
    423423 
     424// Hash size for secret key check 
     425#define OPS_CHECKHASH_SIZE      20 
     426 
    424427/** ops_secret_key_t 
    425428 */ 
     
    432435    ops_hash_algorithm_t        hash_algorithm; 
    433436    unsigned char               salt[OPS_SALT_SIZE]; 
    434     unsigned                    iterations
     437    unsigned                    octet_count
    435438    unsigned char               iv[OPS_MAX_BLOCK_SIZE]; 
     439    ops_secret_key_union_t      key; 
    436440    unsigned                    checksum; 
    437     ops_secret_key_union_t     key
     441    unsigned char              checkhash[OPS_CHECKHASH_SIZE]
    438442    } ops_secret_key_t; 
    439443 
  • openpgpsdk/trunk/src/packet-parse.c

    r342 r343  
    17931793    ops_region_t encregion; 
    17941794    ops_region_t *saved_region=NULL; 
     1795    size_t checksum_length=2; 
    17951796 
    17961797    memset(&content,'\0',sizeof content); 
     
    18001801        return 0; 
    18011802    C.secret_key.s2k_usage=c[0]; 
     1803 
     1804    if(C.secret_key.s2k_usage == OPS_S2KU_ENCRYPTED_AND_HASHED) 
     1805        checksum_length=20; 
    18021806 
    18031807    if(C.secret_key.s2k_usage == OPS_S2KU_ENCRYPTED 
     
    18281832            if(!limited_read(c,1,region,parse_info)) 
    18291833                return 0; 
    1830             C.secret_key.iterations=(16+(c[0]&15)) << ((c[0] >> 4)+6); 
     1834            C.secret_key.octet_count=(16+(c[0]&15)) << ((c[0] >> 4)+6); 
    18311835            } 
    18321836        } 
     
    18461850        ops_parser_content_t pc; 
    18471851        char *passphrase; 
    1848         unsigned char hash[OPS_MAX_HASH]; 
     1852        unsigned char key[OPS_MAX_KEY_SIZE+OPS_MAX_HASH_SIZE]; 
     1853        ops_hash_t hashes[(OPS_MAX_KEY_SIZE+OPS_MIN_HASH_SIZE-1)/OPS_MIN_HASH_SIZE]; 
     1854        int keysize; 
     1855        int hashsize; 
     1856        size_t l; 
    18491857 
    18501858        n=ops_block_size(C.secret_key.algorithm); 
     
    18671875            } 
    18681876 
    1869         ops_hash(hash,C.secret_key.hash_algorithm,passphrase, 
    1870                  strlen(passphrase)); 
     1877        keysize=ops_key_size(C.secret_key.algorithm); 
     1878        assert(keysize > 0 && keysize <= OPS_MAX_KEY_SIZE); 
     1879 
     1880        hashsize=ops_hash_size(C.secret_key.hash_algorithm); 
     1881        assert(hashsize > 0 && hashsize <= OPS_MAX_HASH_SIZE); 
     1882 
     1883        for(n=0 ; n*hashsize < keysize ; ++n) 
     1884            { 
     1885            int i; 
     1886 
     1887            ops_hash_any(&hashes[n],C.secret_key.hash_algorithm); 
     1888            hashes[n].init(&hashes[n]); 
     1889            // preload hashes with zeroes... 
     1890            for(i=0 ; i < n ; ++i) 
     1891                hashes[n].add(&hashes[n],"",1); 
     1892            } 
     1893 
     1894        l=strlen(passphrase); 
     1895 
     1896        for(n=0 ; n*hashsize < keysize ; ++n) 
     1897            { 
     1898            unsigned i; 
     1899 
     1900            switch(C.secret_key.s2k_specifier) 
     1901                { 
     1902            case OPS_S2KS_SALTED: 
     1903                hashes[n].add(&hashes[n],C.secret_key.salt,OPS_SALT_SIZE); 
     1904                // flow through... 
     1905            case OPS_S2KS_SIMPLE: 
     1906                hashes[n].add(&hashes[n],passphrase,l); 
     1907                break; 
     1908 
     1909            case OPS_S2KS_ITERATED_AND_SALTED: 
     1910                for(i=0 ; i < C.secret_key.octet_count ; i+=l+OPS_SALT_SIZE) 
     1911                    { 
     1912                    int j=l+OPS_SALT_SIZE; 
     1913 
     1914                    if(i+j > C.secret_key.octet_count && i != 0) 
     1915                        j=C.secret_key.octet_count-i; 
     1916 
     1917                    hashes[n].add(&hashes[n],C.secret_key.salt, 
     1918                                  j > OPS_SALT_SIZE ? OPS_SALT_SIZE : j); 
     1919                    if(j > OPS_SALT_SIZE) 
     1920                        hashes[n].add(&hashes[n],passphrase,j-OPS_SALT_SIZE); 
     1921                    } 
     1922                         
     1923                } 
     1924            } 
     1925 
     1926        for(n=0 ; n*hashsize < keysize ; ++n) 
     1927            { 
     1928            int r=hashes[n].finish(&hashes[n],key+n*hashsize); 
     1929            assert(r == hashsize); 
     1930            } 
    18711931 
    18721932        ops_decrypt_any(&decrypt,C.secret_key.algorithm); 
    18731933        decrypt.set_iv(&decrypt,C.secret_key.iv); 
    1874         decrypt.set_key(&decrypt,hash); 
    1875  
     1934        decrypt.set_key(&decrypt,key); 
     1935 
     1936        /* We need to prevent the decrypter from reading the trailing 
     1937           checksum */ 
     1938        region->length-=checksum_length; 
    18761939        ops_reader_push_decrypt(parse_info,&decrypt,region); 
    18771940 
    1878         /* Since all known encryption for PGP doesn't compress, we can limit 
    1879            to the same length as the current region (for now) */ 
     1941        /* Since all known encryption for PGP doesn't compress, we can 
     1942           limit to the same length as the current region (for now), 
     1943           allowing for the trailing checksum. 
     1944        */ 
     1945 
    18801946        ops_init_subregion(&encregion,NULL); 
    18811947        encregion.length=region->length-region->length_read; 
     
    19121978        { 
    19131979        ops_reader_pop_decrypt(parse_info); 
     1980        assert(region->length_read == region->length); 
    19141981        region=saved_region; 
     1982        /* put back checksum data */ 
     1983        region->length+=checksum_length; 
    19151984        } 
    19161985 
     
    19181987        return 0; 
    19191988 
    1920     if(!limited_read_scalar(&C.secret_key.checksum,2,region,parse_info)) 
    1921         return 0; 
    19221989    // XXX: check the checksum 
     1990 
     1991    if(C.secret_key.s2k_usage == OPS_S2KU_ENCRYPTED_AND_HASHED) 
     1992        { 
     1993        if(!limited_read(C.secret_key.checkhash,20,region,parse_info)) 
     1994            return 0; 
     1995        } 
     1996    else 
     1997        { 
     1998        if(!limited_read_scalar(&C.secret_key.checksum,2,region,parse_info)) 
     1999            return 0; 
     2000        } 
    19232001 
    19242002    CBP(parse_info,OPS_PTAG_CT_SECRET_KEY,&content); 
  • openpgpsdk/trunk/src/signature.c

    r319 r343  
    218218    { 
    219219    int n; 
    220     unsigned char hashout[OPS_MAX_HASH]; 
     220    unsigned char hashout[OPS_MAX_HASH_SIZE]; 
    221221 
    222222    n=hash->finish(hash,hashout); 
  • openpgpsdk/trunk/src/symmetric.c

    r341 r343  
    44#include <openssl/cast.h> 
    55 
    6 unsigned ops_block_size(ops_symmetric_algorithm_t alg) 
    7     { 
    8     // perhaps do this via the underlying algorithm later 
    9     switch(alg) 
    10         { 
    11     case OPS_SA_PLAINTEXT: 
    12         return 1; 
    13  
    14     case OPS_SA_IDEA: 
    15     case OPS_SA_TRIPLEDES: 
    16     case OPS_SA_CAST5: 
    17     case OPS_SA_BLOWFISH: 
    18     case OPS_SA_TWOFISH: 
    19         return 8; 
    20  
    21     case OPS_SA_AES_128: 
    22     case OPS_SA_AES_192: 
    23     case OPS_SA_AES_256: 
    24         return 16; 
    25         } 
    26  
    27     return 0; 
    28     } 
    29  
    306typedef struct 
    317    { 
    328    unsigned char decrypted[1024]; 
    339    size_t decrypted_count; 
     10    size_t decrypted_offset; 
    3411    ops_decrypt_t *decrypt; 
    3512    ops_region_t *region; 
     
    5936                n=length; 
    6037 
    61             memcpy(dest,arg->decrypted,n); 
     38            memcpy(dest,arg->decrypted+arg->decrypted_offset,n); 
    6239            arg->decrypted_count-=n; 
     40            arg->decrypted_offset+=n; 
    6341            length-=n; 
    6442            dest+=n; 
     
    8967                                                       buffer,n); 
    9068            assert(arg->decrypted_count > 0); 
     69 
     70            arg->decrypted_offset=0; 
    9171            } 
    9272        } 
     
    174154    }; 
    175155 
    176 void ops_decrypt_any(ops_decrypt_t *decrypt,ops_symmetric_algorithm_t alg) 
     156static ops_decrypt_t *get_proto(ops_symmetric_algorithm_t alg) 
    177157    { 
    178158    switch(alg) 
    179159        { 
    180160    case OPS_SA_CAST5: 
    181         *decrypt=cast5; 
    182         break; 
     161        return &cast5; 
    183162 
    184163    default: 
    185164        assert(0); 
    186165        } 
     166 
     167    return NULL; 
    187168    } 
    188169 
     170void ops_decrypt_any(ops_decrypt_t *decrypt,ops_symmetric_algorithm_t alg) 
     171    { *decrypt=*get_proto(alg); } 
     172 
     173unsigned ops_block_size(ops_symmetric_algorithm_t alg) 
     174    { 
     175    ops_decrypt_t *p=get_proto(alg); 
     176 
     177    if(!p) 
     178        return 0; 
     179 
     180    return p->blocksize; 
     181    } 
     182 
     183unsigned ops_key_size(ops_symmetric_algorithm_t alg) 
     184    { 
     185    ops_decrypt_t *p=get_proto(alg); 
     186 
     187    if(!p) 
     188        return 0; 
     189 
     190    return p->keysize; 
     191    }