lundi 14 mars 2022

Why the plaintext in libtomcrypt cannot be generated by PRNG(e.g., yarrow)

Firstly, I just tell you the scenario I just met. I WANT to test the efficiency of the aes-ofb in libtomcrypt with different plaintext sizes such as 64, 128, 256 Byte, etc. TO make my codes more automatic, I just would like to use the PRNG to fill up the plaintext. secondly, I just show the function that could fill up the plaintext with yarrow prng.

static inline int PRNG(unsigned char buf[], unsigned int len){
 /* create the seed for the pseudo-random number generator */
unsigned char buf_seed[4];
int err;
std::random_device rd;
int x = (int) rd();
memcpy(buf_seed, &x, sizeof(x));
/* send the buf_seed into the PRNG in libtomcrypt*/
prng_state prng;
if ((err = yarrow_start(&prng))!= CRYPT_OK){
    printf("Start error:%s\n", error_to_string(err));
}
if((err=yarrow_add_entropy(buf_seed, sizeof(buf_seed),&prng))!=CRYPT_OK){
printf("Add_entropy error:%s\n",error_to_string(err));
}
if((err=yarrow_ready(&prng))!=CRYPT_OK){
  printf("Ready error:%s\n",error_to_string(err));
}
yarrow_read(buf,len,&prng);
sprng_done(&prng);
return 0;}

In addition, to make my plaintext could be filled up easily, I just use a pointer array to store the address of different with different sizes. THE corresponding codes like following.

char *plaintext[5];
int len_pt(64);
for (int i = 0; i < 5; i++){
    std::cout << "the length of the plaintext is " << len_pt << std::endl;
    if (i == 4){
        len_pt = 768;
    } 
    plaintext[i] = new char[len_pt];
    PRNG((unsigned char *)plaintext[i], len_pt);
    len_pt *= 2;
}

When I just used this kind of plaintext, my encryption and decryption will apprear erros.

int tom_aes::ofb(char *plaintext, int len_pt){
if (PRNG(this->iv, this->iv_len) != 0){
    std::cout << "[ERROR] PRNG failed!" << std::endl;
}
symmetric_OFB   ofb;
/* temporary variables */
unsigned char *ciphertext = new unsigned char[len_pt];
unsigned char *deciphertext = new unsigned char[len_pt];
/* ENCRYPT */
if ((err = ofb_start(find_cipher("aes"), this->iv, key, sizeof(key), 0, &ofb)) != CRYPT_OK){
    printf("[tom_aes_ofb]ERROR: in %s, %s\n", __func__, error_to_string(err));
    return 0;
}
if ((err = ofb_encrypt((unsigned char*)plaintext, ciphertext, len_pt, &ofb)) != CRYPT_OK){
    printf("[tom_aes_ofb]ERROR: in %s, %s\n", __func__, error_to_string(err));
    return 0;
}

if ((err = ofb_done(&ofb)) != CRYPT_OK){
    printf("[tom_aes_ofb]ERROR: in %s, %s\n", __func__, error_to_string(err));
    return 0;
}

/* DECRYPT */
if ((err = ofb_start(find_cipher("aes"), this->iv, key, sizeof(key), 0, &ofb)) != CRYPT_OK){
    printf("[tom_aes_ofb]ERROR: in %s, %s\n", __func__, error_to_string(err));
    return 0;
}

if ((err = ofb_decrypt(ciphertext, deciphertext, len_pt, &ofb)) != CRYPT_OK){
    printf("[tom_aes_ofb]ERROR: in %s, %s\n", __func__, error_to_string(err));
    return 0;
}

if ((err = ofb_done(&ofb)) != CRYPT_OK){
    printf("[tom_aes_ofb]ERROR: in %s, %s\n", __func__, error_to_string(err));
    return 0;
}

if (memcmp(deciphertext, plaintext, len_pt) == 0){
    printf("\n[tom_aes_ofb]Recovery:       OK\n");
}
else{
    printf("\n[tom_aes_ofb]Recovery:       FAIL\n");
}
delete ciphertext;
delete deciphertext;
return 0;} 

I have just tested above codes. When the plaintext is just like:

char            plaintext[] = "Hi I am an AES ECB test vector distributed on 4 128-bit blocks!";

The encryption and decryption could execute smooothly. But the plaintext filled up by my prng function will be destroyted. I cannot figure it out. Wish you could give a hand.

Aucun commentaire:

Enregistrer un commentaire