static void cts_dec (unsigned char *out, unsigned char *in, unsigned char *iv, unsigned int len) { int r; unsigned int len2; unsigned char pn1[B], pn[B], cn[B], cn1[B]; if (len < B + 1) abort (); len2 = (len - B - 1) & ~(B-1); cbc_dec (out, in, iv, len2); out += len2; in += len2; len -= len2; if (len2) iv = in - B; if (len <= B || len > 2 * B) abort (); memcpy (cn1, in, B); r = aes_dec_blk (cn1, pn, &dctx); if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); memset (cn, 0, sizeof(cn)); memcpy (cn, in+B, len-B); xor (pn, pn, cn); memcpy (cn+len-B, pn+len-B, 2*B-len); r = aes_dec_blk (cn, pn1, &dctx); if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); xor (pn1, pn1, iv); memcpy(out, pn1, B); memcpy(out+B, pn, len-B); }
static void ecb_dec (unsigned char *out, unsigned char *in, unsigned int len) { unsigned int i, r; for (i = 0; i < len; i += 16) { r = aes_dec_blk (in + i, out + i, &dctx); if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); } if (i != len) abort (); }
BOOL CEncrypt::AesDecrypt(const char* szInDataBuff, uint32_t nInDataSize, char* szOutDataBuff, uint32_t& nOutDataSize) { assert(m_stAesDecryCtx.n_rnd != 0); assert(nOutDataSize >= nInDataSize); nOutDataSize = 0; while (nOutDataSize < nInDataSize) { aes_dec_blk((const unsigned char *)(szInDataBuff + nOutDataSize), (unsigned char *)(szOutDataBuff + nOutDataSize),&m_stAesDecryCtx); nOutDataSize += AES_BLOCK_SIZE; } return TRUE; }
static void cbc_dec (unsigned char *out, unsigned char *in, unsigned char *iv, unsigned int len) { unsigned int i, r; unsigned char tmp[B]; memcpy (tmp, iv, B); for (i = 0; i < len; i += B) { r = aes_dec_blk (in + i, tmp, &dctx); if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); xor (tmp, tmp, iv); iv = in + i; memcpy (out + i, tmp, B); } if (i != len) abort (); }
static void fips_test () { static const unsigned char fipskey[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, }; static const unsigned char input[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, }; static const unsigned char expected[16] = { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a, }; unsigned char output[16]; unsigned char tmp[16]; aes_ctx fipsctx; int r; printf ("FIPS test:\nkey:"); hexdump (fipskey, 16); printf ("\ninput:"); hexdump (input, 16); r = aes_enc_key (fipskey, sizeof(fipskey), &fipsctx); if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); r = aes_enc_blk (input, output, &fipsctx); if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); printf ("\noutput:"); hexdump (output, 16); printf ("\n"); if (memcmp(expected, output, 16)) fprintf(stderr, "wrong results!!!\n"), exit (1); r = aes_dec_key (fipskey, sizeof(fipskey), &fipsctx); if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); r = aes_dec_blk (output, tmp, &fipsctx); if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); if (memcmp(input, tmp, 16)) fprintf(stderr, "decryption failed!!\n"), exit(1); printf ("ok.\n\n"); }
static void aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) { aes_dec_blk(crypto_tfm_ctx(tfm), dst, src); }
void crypto_aes_decrypt_x86(struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src) { aes_dec_blk(ctx, dst, src); }
static inline void dec(char *out, const char *in, aes_ctx *ctx) { if (aes_dec_blk((const unsigned char *)in, (unsigned char *)out, ctx) != aes_good) abort(); }
int decfile(FILE *fin, FILE *fout, aes_ctx *ctx, const char* ifn, const char* ofn) { char buf1[BLOCK_LEN], buf2[BLOCK_LEN], dbuf[2 * BLOCK_LEN]; char *b1, *b2, *bt; fpos_t flen; unsigned long i, len, rlen; // find the file length fseek(fin, 0, SEEK_END); fgetpos(fin, &flen); rlen = file_len(flen); // reset to start fseek(fin, 0, SEEK_SET); if(rlen <= 2 * BLOCK_LEN) { // if the original file length is less than or equal to 16 bytes // read the bytes of the file and verify length len = (unsigned long)fread(dbuf, 1, 2 * BLOCK_LEN, fin); rlen -= len; if(rlen > 0) return READ_ERROR; // set the original file length len -= BLOCK_LEN; // decrypt from position len to position len + BLOCK_LEN aes_dec_blk(dbuf + len, dbuf + BLOCK_LEN, ctx); // undo CBC chaining for(i = 0; i < len; ++i) dbuf[i] ^= dbuf[i + BLOCK_LEN]; // output decrypted bytes if(fwrite(dbuf, 1, len, fout) != len) return WRITE_ERROR; } else { // we need two input buffers because we have to keep the previous // ciphertext block - the pointers b1 and b2 are swapped once per // loop so that b2 points to new ciphertext block and b1 to the // last ciphertext block rlen -= BLOCK_LEN; b1 = buf1; b2 = buf2; // input the IV if(fread(b1, 1, BLOCK_LEN, fin) != BLOCK_LEN) return READ_ERROR; // read the encrypted file a block at a time while(rlen > 0 && !feof(fin)) { // input a block and reduce the remaining byte count len = (unsigned long)fread(b2, 1, BLOCK_LEN, fin); rlen -= len; // verify the length of the read operation if(len != BLOCK_LEN) return READ_ERROR; // decrypt input buffer aes_dec_blk(b2, dbuf, ctx); // if there is only one more block do ciphertext stealing if(rlen > 0 && rlen < BLOCK_LEN) { // read last ciphertext block if(fread(b2, 1, rlen, fin) != rlen) return READ_ERROR; // append high part of last decrypted block for(i = rlen; i < BLOCK_LEN; ++i) b2[i] = dbuf[i]; // decrypt last block of plaintext for(i = 0; i < rlen; ++i) dbuf[i + BLOCK_LEN] = dbuf[i] ^ b2[i]; // decrypt last but one block of plaintext aes_dec_blk(b2, dbuf, ctx); // adjust length of last output block len = rlen + BLOCK_LEN; rlen = 0; } // unchain CBC using the last ciphertext block for(i = 0; i < BLOCK_LEN; ++i) dbuf[i] ^= b1[i]; // write decrypted block if(fwrite(dbuf, 1, len, fout) != len) return WRITE_ERROR; // swap the buffer pointers bt = b1, b1 = b2, b2 = bt; } } return 0; }