Changeset 357

Show
Ignore:
Timestamp:
02/06/06 17:37:13
Author:
ben
Message:

Hoorah! V3 keys work. What a mess.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • openpgpsdk/trunk/include/openpgpsdk/crypto.h

    r346 r357  
    3333                                   const unsigned char *key); 
    3434typedef void ops_decrypt_init_t(ops_decrypt_t *decrypt); 
     35typedef void ops_decrypt_resync_t(ops_decrypt_t *decrypt); 
    3536typedef size_t ops_decrypt_decrypt_t(ops_decrypt_t *decrypt,void *out, 
    3637                                     const void *in,int count); 
     
    4546    ops_decrypt_set_iv_t *set_key; /* Call this before init! */ 
    4647    ops_decrypt_init_t *init; 
     48    ops_decrypt_resync_t *resync; 
    4749    ops_decrypt_decrypt_t *decrypt; 
    4850    ops_decrypt_finish_t *finish; 
    4951    unsigned char iv[OPS_MAX_BLOCK_SIZE]; 
    5052    unsigned char civ[OPS_MAX_BLOCK_SIZE]; 
     53    unsigned char siv[OPS_MAX_BLOCK_SIZE]; /* Needed for weird v3 resync */ 
    5154    unsigned char key[OPS_MAX_KEY_SIZE]; 
    5255    int num; 
  • openpgpsdk/trunk/src/packet-parse.c

    r354 r357  
    17991799    size_t checksum_length=2; 
    18001800    ops_hash_t checkhash; 
     1801    int blocksize; 
     1802    ops_boolean_t crypted; 
    18011803 
    18021804    memset(&content,'\0',sizeof content); 
     
    18491851        } 
    18501852 
    1851     if(C.secret_key.s2k_usage == OPS_S2KU_ENCRYPTED 
    1852        || C.secret_key.s2k_usage == OPS_S2KU_ENCRYPTED_AND_HASHED) 
     1853    crypted=C.secret_key.s2k_usage == OPS_S2KU_ENCRYPTED 
     1854        || C.secret_key.s2k_usage == OPS_S2KU_ENCRYPTED_AND_HASHED; 
     1855 
     1856    if(crypted) 
    18531857        { 
    18541858        int n; 
     
    18611865        size_t l; 
    18621866 
    1863         n=ops_block_size(C.secret_key.algorithm); 
    1864         assert(n > 0 && n <= OPS_MAX_BLOCK_SIZE); 
    1865  
    1866         if(!limited_read(C.secret_key.iv,n,region,parse_info)) 
     1867        blocksize=ops_block_size(C.secret_key.algorithm); 
     1868        assert(blocksize > 0 && blocksize <= OPS_MAX_BLOCK_SIZE); 
     1869 
     1870        if(!limited_read(C.secret_key.iv,blocksize,region,parse_info)) 
    18671871            return 0; 
    18681872 
     
    19631967 
    19641968    parse_info->reading_v3_secret=C.secret_key.public_key.version != OPS_V4; 
     1969    if(parse_info->reading_v3_secret) 
     1970        { 
     1971        // flagrantly disregard how CFB IV's work... 
     1972        unsigned char iv[OPS_MAX_BLOCK_SIZE]; 
     1973        unsigned char iv2[OPS_MAX_BLOCK_SIZE]; 
     1974 
     1975        memcpy(iv,C.secret_key.iv,blocksize); 
     1976        memset(C.secret_key.iv,'\0',sizeof C.secret_key.iv); 
     1977        decrypt.set_iv(&decrypt,C.secret_key.iv); 
     1978        decrypt.decrypt(&decrypt,iv2,iv,blocksize); 
     1979        } 
    19651980 
    19661981    switch(C.secret_key.public_key.algorithm) 
     
    19982013        checkhash.finish(&checkhash,hash); 
    19992014             
     2015        if(crypted && C.secret_key.public_key.version != OPS_V4) 
     2016            ops_reader_pop_decrypt(parse_info); 
     2017 
    20002018        if(ret) 
    20012019            { 
     
    20122030 
    20132031        sum=ops_reader_pop_sum16(parse_info); 
     2032 
     2033        if(crypted && C.secret_key.public_key.version != OPS_V4) 
     2034            ops_reader_pop_decrypt(parse_info); 
    20142035 
    20152036        if(ret) 
     
    20202041 
    20212042            if(sum != C.secret_key.checksum) 
    2022                 ERRP(parse_info,"Checksum mistmatch in secret key"); 
     2043                ERRP(parse_info,"Checksum mismatch in secret key"); 
    20232044            } 
    20242045        } 
    20252046 
    2026     if(C.secret_key.s2k_usage == OPS_S2KU_ENCRYPTED 
    2027        || C.secret_key.s2k_usage == OPS_S2KU_ENCRYPTED_AND_HASHED) 
    2028         { 
     2047    if(crypted && C.secret_key.public_key.version == OPS_V4) 
    20292048        ops_reader_pop_decrypt(parse_info); 
    2030         assert(!ret || region->length_read == region->length); 
    2031         } 
     2049 
     2050    assert(!ret || region->length_read == region->length); 
    20322051 
    20332052    if(!ret) 
  • openpgpsdk/trunk/src/symmetric.c

    r354 r357  
    3232        { 
    3333        assert(rinfo->pinfo->reading_v3_secret); 
    34         arg->decrypt->init(arg->decrypt); 
     34        arg->decrypt->resync(arg->decrypt); 
    3535        arg->prev_read_was_plain=ops_false; 
    3636        } 
     
    147147    { memcpy(decrypt->key,key,decrypt->keysize); } 
    148148 
     149/* Only IDEA has a resync operation */ 
     150static void std_resync(ops_decrypt_t *decrypt) 
     151    { 
     152    OPS_USED(decrypt); 
     153 
     154    assert(0); 
     155    } 
     156 
    149157static void std_finish(ops_decrypt_t *decrypt) 
    150158    { 
     
    171179    } 
    172180 
    173 #define TRAILER         "","","",0,NULL 
     181#define TRAILER         "","","","",0,NULL 
    174182 
    175183static ops_decrypt_t cast5= 
     
    181189    std_set_key, 
    182190    cast5_init, 
     191    std_resync, 
    183192    cast5_decrypt, 
    184193    std_finish, 
     
    188197static void idea_init(ops_decrypt_t *decrypt) 
    189198    { 
    190     IDEA_KEY_SCHEDULE ks; 
    191  
    192199    assert(decrypt->keysize == IDEA_KEY_LENGTH); 
    193200 
     
    195202    decrypt->data=malloc(sizeof(IDEA_KEY_SCHEDULE)); 
    196203 
    197     idea_set_encrypt_key(decrypt->key,&ks); 
    198     idea_set_decrypt_key(&ks,decrypt->data); 
     204    idea_set_encrypt_key(decrypt->key,decrypt->data); 
     205    // note that we don't invert the key for CFB mode 
    199206 
    200207    memcpy(decrypt->civ,decrypt->iv,decrypt->blocksize); 
     208    memset(decrypt->siv,'\0',sizeof decrypt->siv); 
     209 
    201210    decrypt->num=0; 
    202211    } 
    203212 
    204 static size_t idea_decrypt(ops_decrypt_t *decrypt,void *out,const void *in, 
    205                             int count) 
    206     { 
    207     idea_cfb64_encrypt(in,out,count,decrypt->data,decrypt->civ,&decrypt->num, 
    208                        0); 
    209  
    210     return count; 
     213static void idea_resync(ops_decrypt_t *decrypt) 
     214    { 
     215    if(decrypt->num == 8) 
     216        return; 
     217 
     218    memmove(decrypt->civ+8-decrypt->num,decrypt->civ,decrypt->num); 
     219    memcpy(decrypt->civ,decrypt->siv+decrypt->num,8-decrypt->num); 
     220    decrypt->num=0; 
     221    } 
     222 
     223static size_t idea_decrypt(ops_decrypt_t *decrypt,void *out_,const void *in_, 
     224                           int count) 
     225    { 
     226    unsigned char *out=out_; 
     227    const unsigned char *in=in_; 
     228    int saved=count; 
     229 
     230    /* in order to support v3's weird resyncing we have to implement CFB mode 
     231       ourselves */ 
     232    while(count-- > 0) 
     233        { 
     234        unsigned char t; 
     235 
     236        if(decrypt->num == 8) 
     237            { 
     238            memcpy(decrypt->siv,decrypt->civ,sizeof decrypt->siv); 
     239            idea_ecb_encrypt(decrypt->civ,decrypt->civ,decrypt->data); 
     240            decrypt->num=0; 
     241            } 
     242        t=decrypt->civ[decrypt->num]; 
     243        *out++=t^(decrypt->civ[decrypt->num++]=*in++); 
     244        } 
     245 
     246    return saved; 
    211247    } 
    212248 
     
    219255    std_set_key, 
    220256    idea_init, 
     257    idea_resync, 
    221258    idea_decrypt, 
    222259    std_finish,