Changeset 383

Show
Ignore:
Timestamp:
02/22/06 11:35:13
Author:
ben
Message:

Decrypt session keys. Generalise CFB mode.

Files:

Legend:

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

    r373 r383  
    377377    else 
    378378        printf("Checksum: %04x\n",sk->checksum); 
     379    } 
     380 
     381static void print_pk_session_key(ops_content_tag_t tag, 
     382                                 const ops_pk_session_key_t *key) 
     383    { 
     384    if(tag == OPS_PTAG_CT_PK_SESSION_KEY) 
     385        print_tagname("PUBLIC KEY SESSION KEY"); 
     386    else 
     387        print_tagname("ENCRYPTED PUBLIC KEY SESSION KEY"); 
     388         
     389    printf("Version: %d\n",key->version); 
     390    print_hexdump("key ID",key->key_id,sizeof key->key_id); 
     391    printf("Algorithm: %d (%s)\n",key->algorithm, 
     392           ops_show_pka(key->algorithm)); 
     393    switch(key->algorithm) 
     394        { 
     395    case OPS_PKA_RSA: 
     396        print_bn("encrypted_m",key->parameters.rsa.encrypted_m); 
     397        break; 
     398 
     399    case OPS_PKA_ELGAMAL: 
     400        print_bn("g_to_k",key->parameters.elgamal.g_to_k); 
     401        print_bn("encrypted_m",key->parameters.elgamal.encrypted_m); 
     402        break; 
     403 
     404    default: 
     405        assert(0); 
     406        } 
    379407    } 
    380408 
     
    932960 
    933961    case OPS_PTAG_CT_PK_SESSION_KEY: 
    934         print_tagname("PUBLIC KEY SESSION KEY"); 
    935         printf("Version: %d\n",content->pk_session_key.version); 
    936         print_hexdump("key ID",content->pk_session_key.key_id, 
    937                       sizeof content->pk_session_key.key_id); 
    938         printf("Algorithm: %d (%s)\n",content->pk_session_key.algorithm, 
    939                ops_show_symmetric_algorithm(content->pk_session_key.algorithm)); 
    940         switch(content->pk_session_key.algorithm) 
    941             { 
    942         case OPS_PKA_RSA: 
    943             print_bn("encrypted_m", 
    944                      content->pk_session_key.parameters.rsa.encrypted_m); 
    945             break; 
    946  
    947         case OPS_PKA_ELGAMAL: 
    948             print_bn("g_to_k", 
    949                      content->pk_session_key.parameters.elgamal.g_to_k); 
    950             print_bn("encrypted_m", 
    951                      content->pk_session_key.parameters.elgamal.encrypted_m); 
    952             break; 
    953  
    954         default: 
    955             assert(0); 
    956             } 
    957  
    958         /* Now get hold of session key for later on */ 
     962        print_pk_session_key(content_->tag,&content->pk_session_key); 
     963        break; 
     964 
     965    case OPS_PARSER_CMD_GET_SECRET_KEY: 
     966        print_pk_session_key(OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY, 
     967                             content->get_secret_key.pk_session_key); 
    959968 
    960969        decrypter=ops_keyring_find_key_by_id(&keyring, 
    961                                              content->pk_session_key.key_id); 
     970                                             content->get_secret_key.pk_session_key->key_id); 
    962971        if(!decrypter || !ops_key_is_secret(decrypter)) 
    963972            break; 
     
    973982            free(phrase); 
    974983            } 
     984 
     985        *content->get_secret_key.secret_key=secret; 
    975986         
    976987        break; 
  • openpgpsdk/trunk/include/openpgpsdk/crypto.h

    r373 r383  
    3434typedef void ops_decrypt_init_t(ops_decrypt_t *decrypt); 
    3535typedef void ops_decrypt_resync_t(ops_decrypt_t *decrypt); 
    36 typedef size_t ops_decrypt_decrypt_t(ops_decrypt_t *decrypt,void *out, 
    37                                      const void *in,int count); 
     36//typedef size_t ops_decrypt_decrypt_t(ops_decrypt_t *decrypt,void *out, 
     37//                                   const void *in,int count); 
     38typedef void ops_decrypt_block_encrypt_t(ops_decrypt_t *decrypt,void *out, 
     39                                         const void *in); 
    3840typedef void ops_decrypt_finish_t(ops_decrypt_t *decrypt); 
    3941 
     
    4547    ops_decrypt_set_iv_t *set_iv; /* Call this before init! */ 
    4648    ops_decrypt_set_iv_t *set_key; /* Call this before init! */ 
    47     ops_decrypt_init_t *init; 
     49    ops_decrypt_init_t *base_init; 
    4850    ops_decrypt_resync_t *resync; 
    49     ops_decrypt_decrypt_t *decrypt; 
     51    //    ops_decrypt_decrypt_t *decrypt; 
     52    ops_decrypt_block_encrypt_t *block_encrypt; 
    5053    ops_decrypt_finish_t *finish; 
    5154    unsigned char iv[OPS_MAX_BLOCK_SIZE]; 
     
    5356    unsigned char siv[OPS_MAX_BLOCK_SIZE]; /* Needed for weird v3 resync */ 
    5457    unsigned char key[OPS_MAX_KEY_SIZE]; 
    55     int num; 
     58    size_t num; 
    5659    void *data; 
    5760    }; 
     
    7881                            size_t length,const ops_rsa_secret_key_t *srsa, 
    7982                            const ops_rsa_public_key_t *rsa); 
     83int ops_rsa_private_decrypt(unsigned char *out,const unsigned char *in, 
     84                            size_t length,const ops_rsa_secret_key_t *srsa, 
     85                            const ops_rsa_public_key_t *rsa); 
    8086 
    8187unsigned ops_block_size(ops_symmetric_algorithm_t alg); 
     
    8692 
    8793void ops_decrypt_any(ops_decrypt_t *decrypt,ops_symmetric_algorithm_t alg); 
     94void ops_decrypt_init(ops_decrypt_t *decrypt); 
     95size_t ops_decrypt_decrypt(ops_decrypt_t *decrypt,void *out,const void *in, 
     96                         size_t count); 
    8897 
    8998void ops_reader_push_decrypt(ops_parse_info_t *pinfo,ops_decrypt_t *decrypt, 
     
    95104void ops_reader_pop_hash(ops_parse_info_t *pinfo); 
    96105 
     106int ops_decrypt_mpi(unsigned char *buf,unsigned buflen,const BIGNUM *encmpi, 
     107                    const ops_secret_key_t *skey); 
     108 
    97109#endif 
  • openpgpsdk/trunk/include/openpgpsdk/packet.h

    r373 r383  
    202202    OPS_PTAG_CT_SE_IP_DATA_HEADER       =0x300+13, 
    203203    OPS_PTAG_CT_SE_IP_DATA_BODY         =0x300+14, 
     204    OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY=0x300+15, 
    204205 
    205206    /* commands to the callback */ 
    206207    OPS_PARSER_CMD_GET_SK_PASSPHRASE    =0x400, 
     208    OPS_PARSER_CMD_GET_SECRET_KEY       =0x400+1, 
    207209 
    208210 
     
    809811    { 
    810812    BIGNUM                      *encrypted_m; 
     813    BIGNUM                      *m; 
    811814    } ops_pk_session_key_parameters_rsa_t; 
    812815 
     
    829832    ops_public_key_algorithm_t  algorithm; 
    830833    ops_pk_session_key_parameters_t parameters; 
     834    ops_symmetric_algorithm_t   symmetric_algorithm; 
     835    unsigned char               key[OPS_MAX_KEY_SIZE]; 
     836    unsigned short              checksum; 
    831837    } ops_pk_session_key_t; 
    832838 
     
    852858    unsigned char               data[8192]; 
    853859    } ops_se_data_body_t; 
     860 
     861typedef struct 
     862    { 
     863    const ops_secret_key_t      **secret_key; 
     864    const ops_pk_session_key_t *pk_session_key; 
     865    } ops_get_secret_key_t; 
    854866 
    855867/** ops_parser_union_content_t */ 
     
    901913    ops_se_ip_data_header_t     se_ip_data_header; 
    902914    ops_se_data_body_t          se_data_body; 
     915    ops_get_secret_key_t        get_secret_key; 
    903916    } ops_parser_content_union_t; 
    904917 
  • openpgpsdk/trunk/src/Makefile.template

    r333 r383  
    1212        memory.o fingerprint.o hash.o keyring.o signature.o compress.o \ 
    1313        packet-show.o create.o validate.o lists.o armour.o errors.o \ 
    14         symmetric.o 
     14        symmetric.o crypto.o 
    1515 
    1616headers: 
  • openpgpsdk/trunk/src/keyring.c

    r371 r383  
    285285    return arg.skey; 
    286286    } 
    287  
  • openpgpsdk/trunk/src/openssl_crypto.c

    r371 r383  
    145145    } 
    146146 
     147int ops_rsa_private_decrypt(unsigned char *out,const unsigned char *in, 
     148                            size_t length,const ops_rsa_secret_key_t *srsa, 
     149                            const ops_rsa_public_key_t *rsa) 
     150    { 
     151    RSA *orsa; 
     152    int n; 
     153 
     154    orsa=RSA_new(); 
     155    orsa->n=rsa->n;     // XXX: do we need n? 
     156    orsa->d=srsa->d; 
     157    orsa->p=srsa->q; 
     158    orsa->q=srsa->p; 
     159 
     160    /* debug */ 
     161    orsa->e=rsa->e; 
     162    assert(RSA_check_key(orsa) == 1); 
     163    orsa->e=NULL; 
     164    /* end debug */ 
     165 
     166    n=RSA_private_decrypt(length,in,out,orsa,RSA_NO_PADDING); 
     167 
     168    orsa->n=orsa->d=orsa->p=orsa->q=NULL; 
     169    RSA_free(orsa); 
     170 
     171    return n; 
     172    } 
     173 
    147174void ops_crypto_init() 
    148175    { 
  • openpgpsdk/trunk/src/packet-parse.c

    r373 r383  
    124124/*! \todo descr ERR1 macro */ 
    125125#define ERR1P(info,fmt,x)       do { format_error(&content,(fmt),(x)); CBP(info,OPS_PARSER_ERROR,&content); return ops_false; } while(0) 
     126#define ERR2P(info,fmt,x,y)     do { format_error(&content,(fmt),(x),(y)); CBP(info,OPS_PARSER_ERROR,&content); return ops_false; } while(0) 
    126127 
    127128/* XXX: replace ops_ptag_t with something more appropriate for limiting 
     
    636637    case OPS_PTAG_CT_SE_IP_DATA_HEADER: 
    637638    case OPS_PTAG_CT_SE_IP_DATA_BODY: 
     639    case OPS_PARSER_CMD_GET_SECRET_KEY: 
    638640        break; 
    639641 
     
    20642066    unsigned char c[1]; 
    20652067    ops_parser_content_t content; 
     2068    ops_parser_content_t pc; 
     2069    unsigned char buf[8192]; 
     2070    int n; 
     2071    BIGNUM *enc_m; 
     2072    unsigned k; 
     2073    const ops_secret_key_t *secret; 
    20662074 
    20672075    if(!limited_read(c,1,region,parse_info)) 
     
    20862094                             region,parse_info)) 
    20872095            return 0; 
     2096        enc_m=C.pk_session_key.parameters.rsa.encrypted_m; 
    20882097        break; 
    20892098 
     
    20942103                             region,parse_info)) 
    20952104            return 0; 
     2105        enc_m=C.pk_session_key.parameters.elgamal.encrypted_m; 
    20962106        break; 
    20972107 
     
    21022112        return 0; 
    21032113        } 
     2114 
     2115    memset(&pc,'\0',sizeof pc); 
     2116    secret=NULL; 
     2117    pc.content.get_secret_key.secret_key=&secret; 
     2118    pc.content.get_secret_key.pk_session_key=&C.pk_session_key; 
     2119 
     2120    CBP(parse_info,OPS_PARSER_CMD_GET_SECRET_KEY,&pc); 
     2121 
     2122    if(!secret) 
     2123        { 
     2124        CBP(parse_info,OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY,&content); 
     2125 
     2126        return 1; 
     2127        } 
     2128 
     2129    n=ops_decrypt_mpi(buf,sizeof buf,enc_m,secret); 
     2130 
     2131    if(n < 1) 
     2132        ERRP(parse_info,"decrypted message too short"); 
     2133 
     2134    C.pk_session_key.symmetric_algorithm=buf[0]; 
     2135    k=ops_key_size(C.pk_session_key.symmetric_algorithm); 
     2136 
     2137    if((unsigned)n != k+3) 
     2138        ERR2P(parse_info,"decrypted message wrong length (got %d expected %d)", 
     2139              n,k+3); 
     2140     
     2141    assert(k <= sizeof C.pk_session_key.key); 
     2142 
     2143    memcpy(C.pk_session_key.key,buf+1,k); 
     2144 
     2145    C.pk_session_key.checksum=buf[k+1]+(buf[k+2] << 8); 
     2146 
     2147    // XXX: Check checksum! 
    21042148 
    21052149    CBP(parse_info,OPS_PTAG_CT_PK_SESSION_KEY,&content); 
  • openpgpsdk/trunk/src/symmetric.c

    r373 r383  
    44#include <openssl/cast.h> 
    55#include <openssl/idea.h> 
     6#include <openssl/aes.h> 
    67#include "parse_local.h" 
    78 
     
    9192            if(!rinfo->pinfo->reading_v3_secret 
    9293               || !rinfo->pinfo->reading_mpi_length) 
    93                 arg->decrypted_count=arg->decrypt->decrypt(arg->decrypt, 
    94                                                            arg->decrypted, 
    95                                                            buffer,n); 
     94                arg->decrypted_count=ops_decrypt_decrypt(arg->decrypt, 
     95                                                         arg->decrypted, 
     96                                                         buffer,n); 
    9697            else 
    9798                { 
     
    117118    arg->region=region; 
    118119 
    119     arg->decrypt->init(arg->decrypt); 
     120    ops_decrypt_init(arg->decrypt); 
    120121 
    121122    ops_reader_push(pinfo,encrypted_data_reader,arg); 
     
    138139    { memcpy(decrypt->key,key,decrypt->keysize); } 
    139140 
    140 /* Only IDEA has a resync operation */ 
    141141static void std_resync(ops_decrypt_t *decrypt) 
    142142    { 
    143     OPS_USED(decrypt); 
    144  
    145     assert(0); 
     143    if(decrypt->num == decrypt->blocksize) 
     144        return; 
     145 
     146    memmove(decrypt->civ+decrypt->blocksize-decrypt->num,decrypt->civ, 
     147            decrypt->num); 
     148    memcpy(decrypt->civ,decrypt->siv+decrypt->num, 
     149           decrypt->blocksize-decrypt->num); 
     150    decrypt->num=0; 
    146151    } 
    147152 
     
    157162    decrypt->data=malloc(sizeof(CAST_KEY)); 
    158163    CAST_set_key(decrypt->data,decrypt->keysize,decrypt->key); 
    159     memcpy(decrypt->civ,decrypt->iv,decrypt->blocksize); 
    160     decrypt->num=0; 
    161     } 
    162  
    163 static size_t cast5_decrypt(ops_decrypt_t *decrypt,void *out,const void *in, 
    164                             int count) 
    165     { 
    166     CAST_cfb64_encrypt(in,out,count,decrypt->data,decrypt->civ,&decrypt->num, 
    167                        0); 
    168  
    169     return count; 
    170     } 
     164    } 
     165 
     166static void cast5_encrypt(ops_decrypt_t *decrypt,void *out,const void *in) 
     167    { CAST_ecb_encrypt(in,out,decrypt->data,1); } 
    171168 
    172169#define TRAILER         "","","","",0,NULL 
     
    181178    cast5_init, 
    182179    std_resync, 
    183     cast5_decrypt, 
     180    cast5_encrypt, 
    184181    std_finish, 
    185182    TRAILER 
     
    195192    // note that we don't invert the key for CFB mode 
    196193    idea_set_encrypt_key(decrypt->key,decrypt->data); 
    197  
    198     memcpy(decrypt->civ,decrypt->iv,decrypt->blocksize); 
    199     idea_ecb_encrypt(decrypt->civ,decrypt->siv,decrypt->data); 
    200  
    201     decrypt->num=0; 
    202     } 
    203  
    204 static void idea_resync(ops_decrypt_t *decrypt) 
    205     { 
    206     if(decrypt->num == 8) 
    207         return; 
    208  
    209     memmove(decrypt->civ+8-decrypt->num,decrypt->civ,decrypt->num); 
    210     memcpy(decrypt->civ,decrypt->siv+decrypt->num,8-decrypt->num); 
    211     decrypt->num=0; 
    212     } 
    213  
    214 static size_t idea_decrypt(ops_decrypt_t *decrypt,void *out_,const void *in_, 
    215                            int count) 
    216     { 
    217     unsigned char *out=out_; 
    218     const unsigned char *in=in_; 
    219     int saved=count; 
    220  
    221     /* in order to support v3's weird resyncing we have to implement CFB mode 
    222        ourselves */ 
    223     while(count-- > 0) 
    224         { 
    225         unsigned char t; 
    226  
    227         if(decrypt->num == 8) 
    228             { 
    229             memcpy(decrypt->siv,decrypt->civ,sizeof decrypt->siv); 
    230             idea_ecb_encrypt(decrypt->civ,decrypt->civ,decrypt->data); 
    231             decrypt->num=0; 
    232             } 
    233         t=decrypt->civ[decrypt->num]; 
    234         *out++=t^(decrypt->civ[decrypt->num++]=*in++); 
    235         } 
    236  
    237     return saved; 
    238     } 
    239  
    240 static ops_decrypt_t idea= 
     194    } 
     195 
     196static void idea_block_encrypt(ops_decrypt_t *decrypt,void *out,const void *in) 
     197    { idea_ecb_encrypt(in,out,decrypt->data); } 
     198 
     199static const ops_decrypt_t idea= 
    241200    { 
    242201    OPS_SA_IDEA, 
     
    246205    std_set_key, 
    247206    idea_init, 
    248     idea_resync, 
    249     idea_decrypt, 
     207    std_resync, 
     208    idea_block_encrypt, 
    250209    std_finish, 
    251210    TRAILER 
    252211    }; 
    253212 
    254 static ops_decrypt_t *get_proto(ops_symmetric_algorithm_t alg) 
     213static void aes256_init(ops_decrypt_t *decrypt) 
     214    { 
     215    free(decrypt->data); 
     216    decrypt->data=malloc(sizeof(AES_KEY)); 
     217    AES_set_encrypt_key(decrypt->key,256,decrypt->data); 
     218    } 
     219 
     220static void aes_block_encrypt(ops_decrypt_t *decrypt,void *out,const void *in) 
     221    { AES_encrypt(in,out,decrypt->data); } 
     222 
     223static const ops_decrypt_t aes256= 
     224    { 
     225    OPS_SA_AES_256, 
     226    AES_BLOCK_SIZE, 
     227    256/8, 
     228    std_set_iv, 
     229    std_set_key, 
     230    aes256_init, 
     231    std_resync, 
     232    aes_block_encrypt, 
     233    std_finish, 
     234    TRAILER 
     235    }; 
     236 
     237static const ops_decrypt_t *get_proto(ops_symmetric_algorithm_t alg) 
    255238    { 
    256239    switch(alg) 
     
    262245        return &idea; 
    263246 
     247    case OPS_SA_AES_256: 
     248        return &aes256; 
     249 
    264250    default: 
     251        // XXX: remove these 
     252        fprintf(stderr,"Unknown algorithm: %d\n",alg); 
    265253        assert(0); 
    266254        } 
     
    274262unsigned ops_block_size(ops_symmetric_algorithm_t alg) 
    275263    { 
    276     ops_decrypt_t *p=get_proto(alg); 
     264    const ops_decrypt_t *p=get_proto(alg); 
    277265 
    278266    if(!p) 
     
    284272unsigned ops_key_size(ops_symmetric_algorithm_t alg) 
    285273    { 
    286     ops_decrypt_t *p=get_proto(alg); 
     274    const ops_decrypt_t *p=get_proto(alg); 
    287275 
    288276    if(!p) 
     
    291279    return p->keysize; 
    292280    } 
     281 
     282void ops_decrypt_init(ops_decrypt_t *decrypt) 
     283    { 
     284    decrypt->base_init(decrypt); 
     285    memcpy(decrypt->civ,decrypt->iv,decrypt->blocksize); 
     286    decrypt->block_encrypt(decrypt,decrypt->siv,decrypt->civ); 
     287    decrypt->num=0; 
     288    } 
     289 
     290size_t ops_decrypt_decrypt(ops_decrypt_t *decrypt,void *out_,const void *in_, 
     291                           size_t count) 
     292    { 
     293    unsigned char *out=out_; 
     294    const unsigned char *in=in_; 
     295    int saved=count; 
     296 
     297    /* in order to support v3's weird resyncing we have to implement CFB mode 
     298       ourselves */ 
     299    while(count-- > 0) 
     300        { 
     301        unsigned char t; 
     302 
     303        if(decrypt->num == decrypt->blocksize) 
     304            { 
     305            memcpy(decrypt->siv,decrypt->civ,decrypt->blocksize); 
     306            decrypt->block_encrypt(decrypt,decrypt->civ,decrypt->civ); 
     307            decrypt->num=0; 
     308            } 
     309        t=decrypt->civ[decrypt->num]; 
     310        *out++=t^(decrypt->civ[decrypt->num++]=*in++); 
     311        } 
     312 
     313    return saved; 
     314    } 
     315