void DB_AuthLoad_InflateInit_decryptFunc(z_stream* strm) { if (ffVersion < 319) { return; } ctr_decrypt(strm->next_in, strm->next_in, strm->avail_in, &ffCTR); }
void DB_AuthLoad_Inflate_decryptBaseFunc(unsigned char* buffer) { if (ffVersion < 319) { return; } ctr_setiv(ffIV, sizeof(ffIV), &ffCTR); ctr_decrypt(buffer, buffer, 8192, &ffCTR); }
int eax_decryptx( const unsigned char ct[], unsigned char pt[], unsigned long length, eax_state eax[1] ) { int err; if( (err = omac_process( ct, length, eax->ctx_omac )) != EXIT_SUCCESS ) return err; return ctr_decrypt( ct, pt, length, eax->ctr ); }
void authenticate_decrypt(void* buf, u32 len) { #ifdef GLADMAN_HMAC hmac_sha1_data(buf, len, &hmac); #else if (hmac_process(&hmac, buf, len) != CRYPT_OK) Z_ERROR("Failed to authenticate"); #endif if (ctr_decrypt(buf, buf, len, &ctr) != CRYPT_OK) Z_ERROR("Failed to decrypt"); }
void DB_AuthLoad_Inflate_compare(unsigned char* buffer, int length, unsigned char* ivValue) { if (ffVersion < 319) { return; } // we don't do anything return-like here, as this is just hash comparing, and we don't care about the data after this at all ctr_setiv(ivValue, 16, &ffCTR); ctr_decrypt(buffer, buffer, length, &ffCTR); }
int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt, unsigned long length) { int err; LTC_ARGCHK(eax != NULL); LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); /* omac ciphertext */ if ((err = omac_process(&eax->ctomac, ct, length)) != CRYPT_OK) { return err; } /* decrypt */ return ctr_decrypt(ct, pt, length, &eax->ctr); }
int symmetricDecrypt(unsigned char *key, unsigned long keylen, unsigned char *in, unsigned long len, unsigned char *IV, unsigned long ivlen) { symmetric_CTR ctr; int err; /* register aes first */ if (register_cipher(&rijndael_desc) == -1) { return ERROR_REG_AES; } /* start up CTR mode */ if ((err = ctr_start( find_cipher("rijndael"), /* index of desired cipher */ IV, /* the initial vecoter */ key, /* the secret key */ keylen, /* length of secret key */ 0, CTR_COUNTER_LITTLE_ENDIAN, &ctr) ) != CRYPT_OK) { return err; } // if ((err = ctr_setiv( IV, /* the initial IV we gave to ctr_start */ // 16, /* the IV is 16 bytes long */ // &ctr) /* the ctr state we wish to modify */ // ) != CRYPT_OK) { // printf("ctr_setiv error: %s\n", error_to_string(err)); // return -1; // } if ((err = ctr_decrypt( in, /* plaintext */ in, /* ciphertext */ len, /* length of plaintext */ &ctr) /* CTR state */ ) != CRYPT_OK) { return err; } if ((err = ctr_done(&ctr)) != CRYPT_OK) { return err; } return CRYPT_OK; }
static int DecryptCTR( int cipher, int rounds, int counterMode, unsigned char *iv, unsigned char *key, unsigned long keyLength, unsigned char *data, unsigned long dataLength, unsigned char *dest ) { int status; symmetric_CTR state; status = ctr_start(cipher, iv, key, keyLength, rounds, counterMode, &state); if (status == CRYPT_OK) { status = ctr_decrypt(data, dest, dataLength, &state); ctr_done(&state); } return status; }
static inline void process_aes_ctr_blocks(void *buffer, void *ctr, uint64_t blocks, uint32_t mode) { ctr_decrypt(buffer, buffer, blocks, mode, ctr); }
int main(){ char plaintext[] = "Hi I am an AES CTR test vector distributed on 4 128-bit blocks!"; unsigned char key[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; unsigned char iv[16] = {0x01, 0xff, 0x83, 0xf2, 0xf9, 0x98, 0xba, 0xa4, 0xda, 0xdc, 0xaa, 0xcc, 0x8e, 0x17, 0xa4, 0x1b}; symmetric_CTR ctr; unsigned char ciphertext[sizeof(plaintext)]; unsigned char deciphertext[sizeof(plaintext)]; int err; if (register_cipher(&aes_desc) == -1) { printf("Error: in %s, unable to register cipher\n", __func__); return 0; } printf("Plaintext: \"%s\"\n", plaintext); printf("IV: "); fprintBuffer_raw(stdout, (char*)iv, sizeof(iv)); printf("\nKey 128: "); fprintBuffer_raw(stdout, (char*)key, sizeof(key)); /* ENCRYPT */ if ((err = ctr_start(find_cipher("aes"), iv, key, sizeof(key), 0, CTR_COUNTER_LITTLE_ENDIAN, &ctr)) != CRYPT_OK){ printf("ERROR: in %s, %s\n", __func__, error_to_string(err)); return 0; } if ((err = ctr_encrypt((unsigned char*)plaintext, ciphertext, sizeof(plaintext), &ctr)) != CRYPT_OK){ printf("ERROR: in %s, %s\n", __func__, error_to_string(err)); return 0; } if ((err = ctr_done(&ctr)) != CRYPT_OK){ printf("ERROR: in %s, %s\n", __func__, error_to_string(err)); return 0; } /* DECRYPT */ if ((err = ctr_start(find_cipher("aes"), iv, key, sizeof(key), 0, CTR_COUNTER_LITTLE_ENDIAN, &ctr)) != CRYPT_OK){ printf("ERROR: in %s, %s\n", __func__, error_to_string(err)); return 0; } if ((err = ctr_decrypt(ciphertext, deciphertext, sizeof(plaintext), &ctr)) != CRYPT_OK){ printf("ERROR: in %s, %s\n", __func__, error_to_string(err)); return 0; } if ((err = ctr_done(&ctr)) != CRYPT_OK){ printf("ERROR: in %s, %s\n", __func__, error_to_string(err)); return 0; } printf("\nCiphertext CTR: "); fprintBuffer_raw(stdout, (char*)ciphertext, sizeof(plaintext)); if (memcmp(deciphertext, plaintext, sizeof(plaintext)) == 0){ printf("\nRecovery: OK\n"); } else{ printf("\nRecovery: FAIL\n"); } return 0; }
int main(int argc, char *argv[]) { unsigned char plaintext[512],ciphertext[512]; unsigned char tmpkey[512], key[MAXBLOCKSIZE], IV[MAXBLOCKSIZE]; unsigned char inbuf[512]; /* i/o block size */ unsigned long outlen, y, ivsize, x, decrypt; symmetric_CTR ctr; int cipher_idx, hash_idx, ks; char *infile, *outfile, *cipher; prng_state prng; FILE *fdin, *fdout; /* register algs, so they can be printed */ register_algs(); if (argc < 4) { return usage(argv[0]); } if (!strcmp(argv[1], "-d")) { decrypt = 1; cipher = argv[2]; infile = argv[3]; outfile = argv[4]; } else { decrypt = 0; cipher = argv[1]; infile = argv[2]; outfile = argv[3]; } /* file handles setup */ fdin = fopen(infile,"rb"); if (fdin == NULL) { perror("Can't open input for reading"); exit(-1); } fdout = fopen(outfile,"wb"); if (fdout == NULL) { perror("Can't open output for writing"); exit(-1); } cipher_idx = find_cipher(cipher); if (cipher_idx == -1) { printf("Invalid cipher entered on command line.\n"); exit(-1); } hash_idx = find_hash("sha256"); if (hash_idx == -1) { printf("LTC_SHA256 not found...?\n"); exit(-1); } ivsize = cipher_descriptor[cipher_idx].block_length; ks = hash_descriptor[hash_idx].hashsize; if (cipher_descriptor[cipher_idx].keysize(&ks) != CRYPT_OK) { printf("Invalid keysize???\n"); exit(-1); } printf("\nEnter key: "); fgets((char *)tmpkey,sizeof(tmpkey), stdin); outlen = sizeof(key); if ((errno = hash_memory(hash_idx,tmpkey,strlen((char *)tmpkey),key,&outlen)) != CRYPT_OK) { printf("Error hashing key: %s\n", error_to_string(errno)); exit(-1); } if (decrypt) { /* Need to read in IV */ if (fread(IV,1,ivsize,fdin) != ivsize) { printf("Error reading IV from input.\n"); exit(-1); } if ((errno = ctr_start(cipher_idx,IV,key,ks,0,CTR_COUNTER_LITTLE_ENDIAN,&ctr)) != CRYPT_OK) { printf("ctr_start error: %s\n",error_to_string(errno)); exit(-1); } /* IV done */ do { y = fread(inbuf,1,sizeof(inbuf),fdin); if ((errno = ctr_decrypt(inbuf,plaintext,y,&ctr)) != CRYPT_OK) { printf("ctr_decrypt error: %s\n", error_to_string(errno)); exit(-1); } if (fwrite(plaintext,1,y,fdout) != y) { printf("Error writing to file.\n"); exit(-1); } } while (y == sizeof(inbuf)); fclose(fdin); fclose(fdout); } else { /* encrypt */ /* Setup yarrow for random bytes for IV */ if ((errno = rng_make_prng(128, find_prng("yarrow"), &prng, NULL)) != CRYPT_OK) { printf("Error setting up PRNG, %s\n", error_to_string(errno)); } /* You can use rng_get_bytes on platforms that support it */ /* x = rng_get_bytes(IV,ivsize,NULL);*/ x = yarrow_read(IV,ivsize,&prng); if (x != ivsize) { printf("Error reading PRNG for IV required.\n"); exit(-1); } if (fwrite(IV,1,ivsize,fdout) != ivsize) { printf("Error writing IV to output.\n"); exit(-1); } if ((errno = ctr_start(cipher_idx,IV,key,ks,0,CTR_COUNTER_LITTLE_ENDIAN,&ctr)) != CRYPT_OK) { printf("ctr_start error: %s\n",error_to_string(errno)); exit(-1); } do { y = fread(inbuf,1,sizeof(inbuf),fdin); if ((errno = ctr_encrypt(inbuf,ciphertext,y,&ctr)) != CRYPT_OK) { printf("ctr_encrypt error: %s\n", error_to_string(errno)); exit(-1); } if (fwrite(ciphertext,1,y,fdout) != y) { printf("Error writing to output.\n"); exit(-1); } } while (y == sizeof(inbuf)); fclose(fdout); fclose(fdin); } return 0; }
int ltc_decrypt(const unsigned char * cipherText, unsigned char * plainText, unsigned int length) { #if defined(ENCRYPTION_ECB) if (ecb_decrypt(cipherText, plainText, length, &sECB) != CRYPT_OK) { #elif defined(ENCRYPTION_CBC) if (cbc_decrypt(cipherText, plainText, length, &sCBC) != CRYPT_OK) { #elif defined(ENCRYPTION_CTR) if (ctr_decrypt(cipherText, plainText, length, &sCTR) != CRYPT_OK) { #endif return 0; } else { return 1; } } #endif //------------------------------------------------------------------------------ /// Decrypts a block of data in CBC mode /// \param Data to decrypt /// \param Buffer to store decrypted data /// \param Length of data /// \return 1 if successful, 0 otherwise. //------------------------------------------------------------------------------ #ifndef ONLY_ONE_ENCRYPTION int ltc_decrypt_CBC(const unsigned char * cipherText, unsigned char * plainText, unsigned int length) { if (cbc_decrypt(cipherText, plainText, length, &sCBC) != CRYPT_OK) { return 0; } else { return 1; } } //------------------------------------------------------------------------------ /// Decrypts a block of data in CTR mode /// \param Data to decrypt /// \param Buffer to store decrypted data /// \param Length of data /// \return 1 if successful, 0 otherwise. //------------------------------------------------------------------------------ int ltc_decrypt_CTR(const unsigned char * cipherText, unsigned char * plainText, unsigned int length) { if (ctr_decrypt(cipherText, plainText, length, &sCTR) != CRYPT_OK) { return 0; } else { return 1; } } //------------------------------------------------------------------------------ /// Decrypts a block of data in ECB mode /// \param Data to decrypt /// \param Buffer to store decrypted data /// \param Length of data /// \return 1 if successful, 0 otherwise. //------------------------------------------------------------------------------ int ltc_decrypt_ECB(const unsigned char * cipherText, unsigned char * plainText, unsigned int length) { if (ecb_decrypt(cipherText, plainText, length, &sECB) != CRYPT_OK) { return 0; } else { return 1; } }
TEE_Result tee_cipher_update(void *ctx, uint32_t algo, TEE_OperationMode mode, bool last_block, const uint8_t *data, size_t len, uint8_t *dst) { TEE_Result res; int ltc_res = CRYPT_OK; size_t block_size; uint8_t tmp_block[64], tmp2_block[64]; int nb_blocks, len_last_block; struct symmetric_CTS *cts; /* * Check that the block contains the correct number of data, apart * for the last block in some XTS / CTR / XTS mode */ res = tee_cipher_get_block_size(algo, &block_size); if (res != TEE_SUCCESS) return res; if ((len % block_size) != 0) { if (!last_block) return TEE_ERROR_BAD_PARAMETERS; switch (algo) { case TEE_ALG_AES_ECB_NOPAD: case TEE_ALG_DES_ECB_NOPAD: case TEE_ALG_DES3_ECB_NOPAD: case TEE_ALG_AES_CBC_NOPAD: case TEE_ALG_DES_CBC_NOPAD: case TEE_ALG_DES3_CBC_NOPAD: return TEE_ERROR_BAD_PARAMETERS; case TEE_ALG_AES_CTR: case TEE_ALG_AES_XTS: case TEE_ALG_AES_CTS: /* * These modes doesn't require padding for the last * block. * * This isn't entirely true, both XTS and CTS can only * encrypt minimum one block and also they need at least * one complete block in the last update to finish the * encryption. The algorithms are supposed to detect * that, we're only making sure that all data fed up to * that point consists of complete blocks. */ break; default: return TEE_ERROR_NOT_SUPPORTED; } } switch (algo) { case TEE_ALG_AES_ECB_NOPAD: case TEE_ALG_DES_ECB_NOPAD: case TEE_ALG_DES3_ECB_NOPAD: if (mode == TEE_MODE_ENCRYPT) ltc_res = ecb_encrypt(data, dst, len, (symmetric_ECB *)ctx); else ltc_res = ecb_decrypt(data, dst, len, (symmetric_ECB *)ctx); break; case TEE_ALG_AES_CBC_NOPAD: case TEE_ALG_DES_CBC_NOPAD: case TEE_ALG_DES3_CBC_NOPAD: if (mode == TEE_MODE_ENCRYPT) ltc_res = cbc_encrypt(data, dst, len, (symmetric_CBC *)ctx); else ltc_res = cbc_decrypt(data, dst, len, (symmetric_CBC *)ctx); break; case TEE_ALG_AES_CTR: if (mode == TEE_MODE_ENCRYPT) ltc_res = ctr_encrypt(data, dst, len, (symmetric_CTR *)ctx); else ltc_res = ctr_decrypt(data, dst, len, (symmetric_CTR *)ctx); break; case TEE_ALG_AES_XTS: return TEE_ERROR_NOT_SUPPORTED; /* if (mode == TEE_MODE_ENCRYPT) { ltc_res = xts_encrypt(data, dst, len, (symmetric_xts *)ctx); } else { ltc_res = xts_decrypt(data, dst, len, (symmetric_xts *)ctx); } */ break; case TEE_ALG_AES_CTS: /* * From http://en.wikipedia.org/wiki/Ciphertext_stealing * CBC ciphertext stealing encryption using a standard * CBC interface: * 1. Pad the last partial plaintext block with 0. * 2. Encrypt the whole padded plaintext using the * standard CBC mode. * 3. Swap the last two ciphertext blocks. * 4. Truncate the ciphertext to the length of the * original plaintext. * * CBC ciphertext stealing decryption using a standard * CBC interface * 1. Dn = Decrypt (K, Cn-1). Decrypt the second to last * ciphertext block. * 2. Cn = Cn || Tail (Dn, B-M). Pad the ciphertext to the * nearest multiple of the block size using the last * B-M bits of block cipher decryption of the * second-to-last ciphertext block. * 3. Swap the last two ciphertext blocks. * 4. Decrypt the (modified) ciphertext using the standard * CBC mode. * 5. Truncate the plaintext to the length of the original * ciphertext. */ cts = (struct symmetric_CTS *)ctx; if (!last_block) return tee_cipher_update( &cts->cbc, TEE_ALG_AES_CBC_NOPAD, mode, last_block, data, len, dst); /* Compute the last block length and check constraints */ if (block_size > 64) return TEE_ERROR_BAD_STATE; nb_blocks = ((len + block_size - 1) / block_size); if (nb_blocks < 2) return TEE_ERROR_BAD_STATE; len_last_block = len % block_size; if (len_last_block == 0) len_last_block = block_size; if (mode == TEE_MODE_ENCRYPT) { memcpy(tmp_block, data + ((nb_blocks - 1) * block_size), len_last_block); memset(tmp_block + len_last_block, 0, block_size - len_last_block); res = tee_cipher_update( &cts->cbc, TEE_ALG_AES_CBC_NOPAD, mode, 0, data, (nb_blocks - 1) * block_size, dst); if (res != TEE_SUCCESS) return res; memcpy(dst + (nb_blocks - 1) * block_size, dst + (nb_blocks - 2) * block_size, len_last_block); res = tee_cipher_update( &cts->cbc, TEE_ALG_AES_CBC_NOPAD, mode, 0, tmp_block, block_size, dst + (nb_blocks - 2) * block_size); if (res != TEE_SUCCESS) return res; } else { /* 1. Decrypt the second to last ciphertext block */ res = tee_cipher_update( &cts->ecb, TEE_ALG_AES_ECB_NOPAD, mode, 0, data + (nb_blocks - 2) * block_size, block_size, tmp2_block); if (res != TEE_SUCCESS) return res; /* 2. Cn = Cn || Tail (Dn, B-M) */ memcpy(tmp_block, data + ((nb_blocks - 1) * block_size), len_last_block); memcpy(tmp_block + len_last_block, tmp2_block + len_last_block, block_size - len_last_block); /* 3. Swap the last two ciphertext blocks */ /* done by passing the correct buffers in step 4. */ /* 4. Decrypt the (modified) ciphertext */ if (nb_blocks > 2) { res = tee_cipher_update( &cts->cbc, TEE_ALG_AES_CBC_NOPAD, mode, 0, data, (nb_blocks - 2) * block_size, dst); if (res != TEE_SUCCESS) return res; } res = tee_cipher_update( &cts->cbc, TEE_ALG_AES_CBC_NOPAD, mode, 0, tmp_block, block_size, dst + ((nb_blocks - 2) * block_size)); if (res != TEE_SUCCESS) return res; res = tee_cipher_update( &cts->cbc, TEE_ALG_AES_CBC_NOPAD, mode, 0, data + ((nb_blocks - 2) * block_size), block_size, tmp_block); if (res != TEE_SUCCESS) return res; /* 5. Truncate the plaintext */ memcpy(dst + (nb_blocks - 1) * block_size, tmp_block, len_last_block); break; } break; default: return TEE_ERROR_NOT_SUPPORTED; } if (ltc_res == CRYPT_OK) return TEE_SUCCESS; else return TEE_ERROR_BAD_STATE; }
unsigned long decode(FILE *fdin, FILE *fdout) { unsigned char plaintext[512],ciphertext[512]; unsigned char tmpkey[512], key[MAXBLOCKSIZE], IV[MAXBLOCKSIZE]; unsigned char inbuf[2048]; /* i/o block size */ unsigned long outlen, y, ivsize, x, wlen; symmetric_CTR ctr; int cipher_idx, hash_idx, ks; char *cipher = "3des"; cipher_idx = find_cipher(cipher); if (cipher_idx == -1) { fprintf(stderr, "Invalid cipher(%s)\n", cipher); exit(-1); } hash_idx = find_hash("sha256"); if (hash_idx == -1) { fprintf(stderr, "SHA256 not found...?\n"); exit(-1); } ivsize = cipher_descriptor[cipher_idx].block_length; ks = hash_descriptor[hash_idx].hashsize; if (cipher_descriptor[cipher_idx].keysize(&ks) != CRYPT_OK) { fprintf(stderr, "Invalid keysize???\n"); exit(-1); } strcpy(tmpkey, EZPUPGKEY) ; outlen = sizeof(key); if ((my_errno = hash_memory(hash_idx,tmpkey,strlen((char *)tmpkey),key,&outlen)) != CRYPT_OK) { fprintf(stderr, "Error hashing key: %s\n", error_to_string(my_errno)); exit(-1); } /* Decrypt only */ /* Need to read in IV */ if (fread(IV,1,ivsize,fdin) != ivsize) { fprintf(stderr, "Error reading IV from input.\n"); exit(-1); } if ((my_errno = ctr_start(cipher_idx,IV,key,ks,0,&ctr)) != CRYPT_OK) { fprintf(stderr, "ctr_start error: %s\n",error_to_string(my_errno)); exit(-1); } wlen = 0 ; /* IV done */ do { y = fread(inbuf,1,sizeof(inbuf),fdin); if ((my_errno = ctr_decrypt(inbuf,plaintext,y,&ctr)) != CRYPT_OK) { fprintf(stderr, "ctr_decrypt error: %s\n", error_to_string(my_errno)); exit(-1); } if (fwrite(plaintext,1,y,fdout) != y) { fprintf(stderr, "Error writing to file.\n"); exit(-1); } wlen += y ; } while (y == sizeof(inbuf)); return wlen; }
int modes_test(void) { unsigned char pt[64], ct[64], tmp[64], key[16], iv[16], iv2[16]; int x, cipher_idx; symmetric_CBC cbc; symmetric_CFB cfb; symmetric_OFB ofb; symmetric_CTR ctr; unsigned long l; /* make a random pt, key and iv */ yarrow_read(pt, 64, &test_yarrow); yarrow_read(key, 16, &test_yarrow); yarrow_read(iv, 16, &test_yarrow); /* get idx of AES handy */ cipher_idx = find_cipher("aes"); if (cipher_idx == -1) { printf("test requires AES"); return 1; } /* test CBC mode */ /* encode the block */ DO(cbc_start(cipher_idx, iv, key, 16, 0, &cbc)); l = sizeof(iv2); DO(cbc_getiv(iv2, &l, &cbc)); if (l != 16 || memcmp(iv2, iv, 16)) { printf("cbc_getiv failed"); return 1; } for (x = 0; x < 4; x++) { DO(cbc_encrypt(pt+x*16, ct+x*16, &cbc)); } /* decode the block */ DO(cbc_setiv(iv2, l, &cbc)); zeromem(tmp, sizeof(tmp)); for (x = 0; x < 4; x++) { DO(cbc_decrypt(ct+x*16, tmp+x*16, &cbc)); } if (memcmp(tmp, pt, 64) != 0) { printf("CBC failed"); return 1; } /* test CFB mode */ /* encode the block */ DO(cfb_start(cipher_idx, iv, key, 16, 0, &cfb)); l = sizeof(iv2); DO(cfb_getiv(iv2, &l, &cfb)); /* note we don't memcmp iv2/iv since cfb_start processes the IV for the first block */ if (l != 16) { printf("cfb_getiv failed"); return 1; } DO(cfb_encrypt(pt, ct, 64, &cfb)); /* decode the block */ DO(cfb_setiv(iv, l, &cfb)); zeromem(tmp, sizeof(tmp)); DO(cfb_decrypt(ct, tmp, 64, &cfb)); if (memcmp(tmp, pt, 64) != 0) { printf("CFB failed"); return 1; } /* test OFB mode */ /* encode the block */ DO(ofb_start(cipher_idx, iv, key, 16, 0, &ofb)); l = sizeof(iv2); DO(ofb_getiv(iv2, &l, &ofb)); if (l != 16 || memcmp(iv2, iv, 16)) { printf("ofb_getiv failed"); return 1; } DO(ofb_encrypt(pt, ct, 64, &ofb)); /* decode the block */ DO(ofb_setiv(iv2, l, &ofb)); zeromem(tmp, sizeof(tmp)); DO(ofb_decrypt(ct, tmp, 64, &ofb)); if (memcmp(tmp, pt, 64) != 0) { printf("OFB failed"); return 1; } /* test CTR mode */ /* encode the block */ DO(ctr_start(cipher_idx, iv, key, 16, 0, &ctr)); l = sizeof(iv2); DO(ctr_getiv(iv2, &l, &ctr)); if (l != 16 || memcmp(iv2, iv, 16)) { printf("ctr_getiv failed"); return 1; } DO(ctr_encrypt(pt, ct, 64, &ctr)); /* decode the block */ DO(ctr_setiv(iv2, l, &ctr)); zeromem(tmp, sizeof(tmp)); DO(ctr_decrypt(ct, tmp, 64, &ctr)); if (memcmp(tmp, pt, 64) != 0) { printf("CTR failed"); return 1; } return 0; }