Пример #1
0
void DAPLUGCALL Daplug_computeDiversifiedKeys(Keyset keys, Keyset *div_keys, char *div){

    char enc_key[GP_KEY_SIZE*2+1]="",
         mac_key[GP_KEY_SIZE*2+1]="",
         dek_key[GP_KEY_SIZE*2+1]="";

    char div_enc_key[GP_KEY_SIZE*2+1]="",
         div_mac_key[GP_KEY_SIZE*2+1]="",
         div_dek_key[GP_KEY_SIZE*2+1]="";

    if(strlen(div)==0 || strlen(div)!=16*2 || !isHexInput(div)){
        fprintf(stderr,"\nDaplug_ComputeDiversifiedKeys(): Wrong value for diversifier !\n");
        return;
    }

    bytesToStr(keys.key[0],GP_KEY_SIZE,enc_key);
    bytesToStr(keys.key[1],GP_KEY_SIZE,mac_key);
    bytesToStr(keys.key[2],GP_KEY_SIZE,dek_key);

    computeDiversifiedKey(enc_key,div,div_enc_key);
    computeDiversifiedKey(mac_key,div,div_mac_key);
    computeDiversifiedKey(dek_key,div,div_dek_key);

    strToBytes(div_enc_key,div_keys->key[0]);
    strToBytes(div_mac_key,div_keys->key[1]);
    strToBytes(div_dek_key,div_keys->key[2]);

}
Пример #2
0
 int DAPLUGCALL keyboard_addHotpCode(Keyboard *k, int flag, int digitsNb, int keysetVersion, int counterFileId, char *div){

    char flag_s[1*2+1]="",
         digitsNb_s[1*2+1]="",
         ksv_s[1*2+1]="",
         cfi_s[2*2+1]="",
         tmp[21*2+1]="";

    sprintf(flag_s,"%02X",flag);
    sprintf(digitsNb_s,"%02X",digitsNb);
    sprintf(ksv_s,"%02X",keysetVersion);
    sprintf(cfi_s,"%04X",counterFileId);

    strcat(tmp,flag_s);
    strcat(tmp,digitsNb_s);
    strcat(tmp,ksv_s);
    if(strcmp(div,"")){
        if(isHexInput(div) && strlen(div)/2 == 16){
            strcat(tmp,div);
        }else{
            fprintf(stderr,"\nkeyboard_addHotpCode(): Invalid diversifier !\n");
            return 0;
        }
    }
    strcat(tmp,cfi_s);

    int len_tmp = strlen(tmp)/2;
    char len_tmp_s[1*2+1]="";
    sprintf(len_tmp_s,"%02X",len_tmp);

    int added_len = strlen("50")+strlen(len_tmp_s)+strlen(tmp);
    added_len = added_len/2;

    if(k->currentContentSize+added_len <= MAX_KB_CONTENT_SIZE){
        strcat(k->content,"50");
        strcat(k->content,len_tmp_s);
        strcat(k->content,tmp);
        k->currentContentSize = k->currentContentSize+added_len;
    }else{
        fprintf(stderr,"\nkeyboard_addReturn(): Keyboard maximum content size exceeded !\n");
        return 0;
    }

    return 1;

}
Пример #3
0
void DAPLUGCALL Daplug_selectPath(DaplugDongle *dpd, char *path){

    if(!isHexInput(path) || strlen(path)%4 != 0){
        fprintf(stderr,"\nselectFile(): Wrong path : %s !\n",path);
        return;
    }

    int i = 0, j = 0, id;

    while(j<strlen(path)/4){
        char *tmp = NULL;
        sscanf(tmp = str_sub(path,i,i+3),"%04X",&id);
        free(tmp);
        tmp = NULL;
        Daplug_selectFile(dpd,id);
        i = i+4;
        j++;

    }

}
Пример #4
0
void DAPLUGCALL Daplug_writeData(DaplugDongle *dpd, int  offset, char* data_to_write){

    Apdu update_binary_apdu;

    char update_binary_apdu_str[APDU_CMD_MAXLEN*2+1]="";
    char pos[2*2+1]="";
    char last_part_len_str[2*2+1]="";

    int p = offset, length = strlen(data_to_write)/2,
        last_part_len = length % MAX_REAL_DATA_SIZE;

    sprintf(last_part_len_str,"%02X",last_part_len);

    if(length%2 !=0 || length <=0 || length + p > MAX_FS_FILE_SIZE || !isHexInput(data_to_write)){
        fprintf(stderr,"\nwriteData(): Wrong data !\n");
        return;
    }

    sprintf(pos,"%04X",p);

    //We write parts of MAX_FS_DATA_RW_SIZE bytes : EF = FF - 8 - 8 (data max len - possible mac - possible pad when enc)
    int write_nb = 0;
    if(length % MAX_REAL_DATA_SIZE== 0) write_nb = length/MAX_REAL_DATA_SIZE; else write_nb = (int)length/MAX_REAL_DATA_SIZE+1;

    char part[MAX_REAL_DATA_SIZE*2+1]="";

    int i = 0;

    while(write_nb > 0){

        strcpy(update_binary_apdu_str,"");
        strcat(update_binary_apdu_str,"80d6");
        strcat(update_binary_apdu_str,pos);

        if(write_nb > 1 || length % MAX_REAL_DATA_SIZE == 0){
            strcat(update_binary_apdu_str,"EF");
            char *tmp = NULL;
            strcpy(part,tmp = str_sub(data_to_write,i,i+MAX_REAL_DATA_SIZE*2-1));
            free(tmp);
            tmp = NULL;
        }else{
            char *tmp = NULL;
            strcat(update_binary_apdu_str,last_part_len_str);
            strcpy(part,tmp = str_sub(data_to_write,i,i+(length%MAX_REAL_DATA_SIZE)*2-1));
            free(tmp);
            tmp = NULL;
        }

        strcat(update_binary_apdu_str,part);

        //Set to apdu cde
        setApduCmd(update_binary_apdu_str,&update_binary_apdu);

        //exchange it
        exchangeApdu(dpd,&update_binary_apdu);

        if(strcmp(update_binary_apdu.sw_str,"9000")){
            fprintf(stderr,"\nwriteData(): Write failure !\n");
            return;
        }

        sscanf(pos,"%04X",&p);
        p = p + MAX_REAL_DATA_SIZE;
        sprintf(pos,"%04X",p);

        i = i+MAX_REAL_DATA_SIZE*2;
        write_nb--;

    }
}
Пример #5
0
void DAPLUGCALL Daplug_authenticate(DaplugDongle *dpd, Keyset keys, int mode, char *div, char *chlg){

    Byte hostChallenge[8];

    char counter[2*2+1] = "",
         cardChallenge[6*2+1] = "",
         returnedCardCryptogram[8*2+1]="",
         computedCardCryptogram[8*2+1]="",
         hostCryptogram[8*2+1] = "",
         s_hostChallenge[8*2+1]="",
         temp[APDU_CMD_MAXLEN*2+1]="";

    Apdu initialize_update,
         external_authenticate;

    //close any sc previously opened
    Daplug_deAuthenticate(dpd);

    if(!strcmp(chlg,"")){
        //generate host challenge
        generateChallenge(hostChallenge,8);
        bytesToStr(hostChallenge,8,s_hostChallenge);
    }else{
        if(strlen(chlg)!=8*2 || !isHexInput(chlg)){
            fprintf(stderr,"\nDaplug_authenticate(): Wrong value for challenge !\n");
            return;
        }
        strncpy(s_hostChallenge,chlg,16);
        s_hostChallenge[16]='\0';
    }

    //Keyset version
    char version[1*2+1]="";
    sprintf(version,"%02X",keys.version);

    //Any diversifier?
    if(strlen(div) != 0){
        if(strlen(div)!=16*2 || !isHexInput(div)){
        fprintf(stderr,"\nDaplug_authenticate(): Wrong value for diversifier !\n");
        return;
        }
    }

    if(strlen(div) == 0){
        //initialize update without diversifier
        strcat(temp,"8050");
        strcat(temp,version);
        strcat(temp,"0008");
        strcat(temp,s_hostChallenge);
        setApduCmd(temp,&initialize_update);
    }else{
        //diversified initialize update
        strcat(temp,"D050");
        strcat(temp,version);
        strcat(temp,"1018");
        strcat(temp,s_hostChallenge);
        strcat(temp,div);
        setApduCmd(temp,&initialize_update);
    }

    //exchange
    exchangeApdu(dpd,&initialize_update);

    if(strcmp(initialize_update.sw_str,"9000")){
        fprintf(stderr,"\nauthenticate(): initialize update error ! sw = %s\n",
                initialize_update.sw_str);
        return;
    }

    //extract data returned by the card
    char *tmp = NULL;
    strcpy(counter,tmp = str_sub(initialize_update.r_str, 24, 27));
    free(tmp);
    tmp = NULL;
    strcpy(cardChallenge,tmp = str_sub(initialize_update.r_str, 28, 39));
    free(tmp);
    tmp = NULL;
    strcpy(returnedCardCryptogram,tmp = str_sub(initialize_update.r_str, 40, 55));
    free(tmp);
    tmp = NULL;

    //compute session keys & update dpd
    char enc_key[GP_KEY_SIZE*2+1]="",
         mac_key[GP_KEY_SIZE*2+1]="",
         dek_key[GP_KEY_SIZE*2+1]="";

    bytesToStr(keys.key[0],GP_KEY_SIZE,enc_key);
    bytesToStr(keys.key[1],GP_KEY_SIZE,mac_key);
    bytesToStr(keys.key[2],GP_KEY_SIZE,dek_key);

    //session s-enc key
    computeSessionKey(counter,"0182",enc_key,dpd->s_enc_key);

    //session s-enc key
    computeSessionKey(counter,"0183",enc_key,dpd->r_enc_key);

    //session c-mac key
    computeSessionKey(counter, "0101", mac_key, dpd->c_mac_key);

    //session r-mac key
    computeSessionKey(counter, "0102", mac_key, dpd->r_mac_key);

    //session dek key. In case of need it will be used. (to form "put key" command for example)
    computeSessionKey(counter,"0181", dek_key, dpd->s_dek_key);

    //compute card cryptogram
    computeCardCryptogram(s_hostChallenge,cardChallenge,counter,dpd->s_enc_key,computedCardCryptogram);

    //check card cryptogram
    if(!checkCardCryptogram(returnedCardCryptogram,computedCardCryptogram)){
        fprintf(stderr,"\nauthenticate(): Card Cryptogram verification failed !\n");
        return;
    }
    else{
        //compute data that an external Daplug_authenticate apdu needs
        computeHostCryptogram(s_hostChallenge, cardChallenge, counter, dpd->s_enc_key, hostCryptogram);

        //mode
        char sec_l[1*2+1]="";
        sprintf(sec_l,"%02X",mode);

        //external Daplug_authenticate
        strcpy(temp,""),
        strcat(temp,"8082");
        strcat(temp,sec_l);
        strcat(temp,"0008");
        strcat(temp,hostCryptogram);
        setApduCmd(temp,&external_authenticate);

        //exchange
        exchangeApdu(dpd,&external_authenticate);

        if(strcmp(external_authenticate.sw_str,"9000")){
            fprintf(stderr,"\nauthenticate(): external Daplug_authenticate error ! sw = %s\n",
                    external_authenticate.sw_str);
            return;
        }

    }

    fprintf(stderr,"\nauthenticate() : Successful authentication !\n");

    //update dpd
    strcpy(dpd->r_mac,dpd->c_mac);
    dpd->securityLevel = mode;
    dpd->session_opened = 1;
}
Пример #6
0
static void encdec(DaplugDongle *dpd, int enc, int keyVersion, int keyID, int mode, char *iv, char *div1, char *div2,
            char *inData, char *outData){

    Apdu enc_dec_apdu;

    char enc_dec_apdu_str[APDU_CMD_MAXLEN*2+1]="";

    char enc_s[1*2+1]="", mode_s[1*2+1]="", kv_s[1*2+1]="", kid_s[1*2+1]="";
    sprintf(enc_s,"%02X",enc);
    sprintf(mode_s,"%02X",mode);
    sprintf(kv_s,"%02X",keyVersion);
    sprintf(kid_s,"%02X",keyID);

    if(enc != 0x01 && enc != 0x02){
        fprintf(stderr,"\nencdec(): Wrong value for enc !\n");
        return;
    }

    char iv_[8*2+1]="";
    if(strlen(iv)==0){
        strcpy(iv_,"0000000000000000");
    }else{
        strcpy(iv_,iv);
    }

    if(!isHexInput(iv_) || strlen(iv_)!=8*2){
        fprintf(stderr,"\nencdec(): Wrong IV !\n");
        return;
    }

    if(mode & ENC_ECB && mode & ENC_CBC){
        fprintf(stderr,"\nencdec(): Wrong mode value !\n");
        return;
    }

    char div1_[16*2+1]="";
    int lc = 10; //kv, kid, iv
    if(mode & ENC_1_DIV || mode & ENC_2_DIV){
        if(strlen(div1)==0 || strlen(div1)!=16*2 || !isHexInput(div1)){
            fprintf(stderr,"\nencdec(): Wrong value for the first diversifier !\n");
            return;
        }else{
            strcpy(div1_,div1);
            lc = lc + 16;
        }
    }

    char div2_[16*2+1]="";
    if(mode & ENC_2_DIV){

        if(strlen(div2)==0 || strlen(div2)!=16*2 || !isHexInput(div2)){
            fprintf(stderr,"\nencdec(): Wrong value for the second diversifier !\n");
            return;
        }else{
            strcpy(div2_,div2);
            lc = lc + 16;
        }
    }

    char data_[(MAX_REAL_DATA_SIZE-10)*2+1]="";

    if(!isHexInput(inData)){
        fprintf(stderr,"\nencdec(): Wrong value for input data !\n");
        return;
    }
    if(strlen(inData) == 0 || strlen(inData)%(8*2) != 0 || lc+strlen(inData)/2 > MAX_REAL_DATA_SIZE){
        fprintf(stderr,"\nencdec(): Wrong length for input data !\n");
        return;
    }

    strcpy(data_,inData);

    lc = lc + strlen(data_)/2;
    char lc_s[1*2+1]="";
    sprintf(lc_s,"%02X",lc);

    //Form the apdu
    strcat(enc_dec_apdu_str,"D020");
    strcat(enc_dec_apdu_str,enc_s);
    strcat(enc_dec_apdu_str,mode_s);
    strcat(enc_dec_apdu_str,lc_s);
    strcat(enc_dec_apdu_str,kv_s);
    strcat(enc_dec_apdu_str,kid_s);
    strcat(enc_dec_apdu_str,iv_);
    strcat(enc_dec_apdu_str,div1_);
    strcat(enc_dec_apdu_str,div2_);
    strcat(enc_dec_apdu_str,data_);

    //Set to apdu cde
    setApduCmd(enc_dec_apdu_str,&enc_dec_apdu);

    //exchange it
    exchangeApdu(dpd,&enc_dec_apdu);

    if(strcmp(enc_dec_apdu.sw_str,"9000")){
        if(enc == 1){
            fprintf(stderr,"\nencdec(): Cannot encrypt data !\n");
        }
        if(enc == 2){
            fprintf(stderr,"\nencdec(): Cannot decrypt data !\n");
        }
        return;
    }

    strcpy(outData,enc_dec_apdu.r_str);

}
Пример #7
0
static void hmac_sha1(DaplugDongle *dpd, int keyVersion, int options, char *div1, char *div2, char* inData, char* outData){

    Apdu hmac_apdu;

    char hmac_apdu_str[APDU_CMD_MAXLEN*2+1]="";

    char kv_s[1*2+1]="";
    sprintf(kv_s,"%02X",keyVersion);

    char opt_s[1*2+1]="";
    sprintf(opt_s,"%02X",options);

    int lc = 0;
    char div1_[16*2+1]="";

    if(options & OTP_1_DIV || options & OTP_2_DIV){
        if(strlen(div1)==0 || strlen(div1)!=16*2 || !isHexInput(div1)){
            fprintf(stderr,"\nhmac_sha1(): Wrong value for the first diversifier !\n");
            return;
        }else{
            strcpy(div1_,div1);
            lc = lc + 16;
        }
    }

    char div2_[16*2+1]="";

    if(options & OTP_2_DIV){

        if(strlen(div2)==0 || strlen(div2)!=16*2 || !isHexInput(div2)){
            fprintf(stderr,"\nhmac_sha1(): Wrong value for the second diversifier !\n");
            return;
        }else{
            strcpy(div2_,div2);
            lc = lc + 16;
        }
    }

    char data_[MAX_REAL_DATA_SIZE*2+1]="";

    if(!isHexInput(inData)){
        fprintf(stderr,"\nhmac_sha1(): Wrong value for input data !\n");
        return;
    }

    if(lc+strlen(inData)/2 > MAX_REAL_DATA_SIZE){ //for Daplug_totp, data can be null => we exclude condition strlen(inData) = 0
        fprintf(stderr,"\nhmac_sha1(): Wrong length for input data !\n");
        return;
    }

    strcpy(data_,inData);

    lc = lc + strlen(data_)/2;
    char lc_s[1*2+1]="";
    sprintf(lc_s,"%02X",lc);

    //Form the apdu
    strcat(hmac_apdu_str,"D022");
    strcat(hmac_apdu_str,kv_s);
    strcat(hmac_apdu_str,opt_s);
    strcat(hmac_apdu_str,lc_s);
    strcat(hmac_apdu_str,div1_);
    strcat(hmac_apdu_str,div2_);
    strcat(hmac_apdu_str,data_);

    //Set to apdu cde
    setApduCmd(hmac_apdu_str,&hmac_apdu);

    //exchange it
    exchangeApdu(dpd,&hmac_apdu);

    if(strcmp(hmac_apdu.sw_str,"9000")){
        fprintf(stderr,"\nhmac_sha1(): Cannot sign data !\n");
        return;
    }

    strcpy(outData,hmac_apdu.r_str);

}