//aes BOOL CEncrypt::AesEncrypt(const char* szInDataBuff, uint32_t nInDataSize, char* szOutDataBuff, uint32_t& nOutDataSize) { assert(m_stAesEncryCtx.n_rnd != 0); assert(nOutDataSize >= ((nInDataSize + AES_BLOCK_SIZE - 1) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE); nOutDataSize = 0; int lnDataLen = nInDataSize - nInDataSize % AES_BLOCK_SIZE; while (nOutDataSize < lnDataLen) { aes_enc_blk((unsigned char *)(szInDataBuff + nOutDataSize), (unsigned char *)(szOutDataBuff + nOutDataSize),&m_stAesEncryCtx); nOutDataSize += AES_BLOCK_SIZE; } if (lnDataLen < nInDataSize) { char lszTmpBuff[AES_BLOCK_SIZE] = {0}; memcpy(lszTmpBuff,szInDataBuff + nOutDataSize,nInDataSize % AES_BLOCK_SIZE); aes_enc_blk((unsigned char *)lszTmpBuff, (unsigned char *)(szOutDataBuff + nOutDataSize),&m_stAesEncryCtx); nOutDataSize += AES_BLOCK_SIZE; } return TRUE; }
ret_type CCM_decrypt(const unsigned char imsg[], /* the plaintext input message */ unsigned char omsg[], /* the encrypted output message */ const mlen_type len, /* the length of this block (bytes) */ CCM_ctx ctx[1]) /* the CCM context */ { mlen_type cnt = (mlen_type)-1, t_cnt = ctx->cnt, hi = ctx->md_len - t_cnt; if(len > hi) { if(len != hi + ctx->af_len) return CCM_msg_length_error; } else hi = len; while(++cnt < hi) { omsg[cnt] = imsg[cnt] ^ ctx->sii[t_cnt & BLOCK_MASK]; /* decrypt message */ ctx->cbc[t_cnt & BLOCK_MASK] ^= omsg[cnt]; /* update the CBC */ if(!(++t_cnt & BLOCK_MASK)) /* if the current encryption block is full */ { inc_ctr(ctx); aes_enc_blk(ctx->blk, ctx->sii, ctx->aes); /* encrypt the CTR value */ aes_enc_blk(ctx->cbc, ctx->cbc, ctx->aes); /* encrypt the running CBC */ } } if(t_cnt == ctx->md_len) /* if at end of message */ { if(t_cnt & BLOCK_MASK) /* if a partial block remains */ aes_enc_blk(ctx->cbc, ctx->cbc, ctx->aes); set_ctr(ctx, 0); /* set CTR to zero */ aes_enc_blk(ctx->blk, ctx->sii, ctx->aes); /* encrypt the CTR */ /* store the encrypted authentication value */ for(t_cnt = 0; t_cnt < ctx->af_len; ++t_cnt) if(imsg[cnt + t_cnt] != (ctx->cbc[t_cnt] ^ ctx->sii[t_cnt])) { /* if bad clear the message and authentication field */ memset(omsg, 0, (size_t)cnt + ctx->af_len); return CCM_auth_failure; } } else ctx->cnt = t_cnt; return (ret_type)cnt; }
static void ecb_enc (unsigned char *out, unsigned char *in, unsigned int len) { unsigned int i, r; for (i = 0; i < len; i += 16) { r = aes_enc_blk (in + i, out + i, &ctx); if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); } if (i != len) abort (); }
ret_type CCM_encrypt(const unsigned char imsg[], /* the plaintext input message */ unsigned char omsg[], /* the encrypted output message */ const mlen_type len, /* the length of this block (bytes) */ CCM_ctx ctx[1]) /* the CCM context */ { mlen_type cnt = (mlen_type)-1, t_cnt = ctx->cnt; if(len > ctx->md_len - t_cnt) return CCM_msg_length_error; while(++cnt < len) { ctx->cbc[t_cnt & BLOCK_MASK] ^= imsg[cnt]; /* update the CBC */ omsg[cnt] = imsg[cnt] ^ ctx->sii[t_cnt & BLOCK_MASK]; /* encrypt message */ if(!(++t_cnt & BLOCK_MASK)) /* if the current encryption block is full */ { inc_ctr(ctx); aes_enc_blk(ctx->blk, ctx->sii, ctx->aes); /* encrypt the CTR value */ aes_enc_blk(ctx->cbc, ctx->cbc, ctx->aes); /* encrypt the running CBC */ } } if(t_cnt == ctx->md_len) /* if at end of message */ { if(t_cnt & BLOCK_MASK) /* if a partial block remains */ aes_enc_blk(ctx->cbc, ctx->cbc, ctx->aes); set_ctr(ctx, 0); /* set CTR to zero */ aes_enc_blk(ctx->blk, ctx->sii, ctx->aes); /* encrypt the CTR */ /* encrypt and store the authentication value */ for(t_cnt = 0; t_cnt < ctx->af_len; ++t_cnt) omsg[cnt + t_cnt] = ctx->cbc[t_cnt] ^ ctx->sii[t_cnt]; cnt += ctx->af_len; } else ctx->cnt = t_cnt; return (ret_type)cnt; }
static void cts_enc (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_enc (out, in, iv, len2); out += len2; in += len2; len -= len2; if (len2) iv = out - B; if (len <= B || len > 2 * B) abort (); printf ("(did CBC mode for %d)\n", len2); D(in); xor (pn1, in, iv); D(pn1); r = aes_enc_blk (pn1, cn, &ctx); if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); D(cn); memset (pn, 0, sizeof(pn)); memcpy (pn, in+B, len-B); D(pn); xor (pn, pn, cn); D(pn); r = aes_enc_blk (pn, cn1, &ctx); if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); D(cn1); memcpy(out, cn1, B); memcpy(out+B, cn, len-B); }
static void cbc_enc (unsigned char *out, unsigned char *in, unsigned char *iv, unsigned int len) { unsigned int i, r; unsigned char tmp[B]; D(iv); memcpy (tmp, iv, B); for (i = 0; i < len; i += B) { D(in+i); xor (tmp, tmp, in + i); D(tmp); r = aes_enc_blk (tmp, out + i, &ctx); if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); memcpy (tmp, out + i, B); D(out+i); } 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_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) { aes_enc_blk(crypto_tfm_ctx(tfm), dst, src); }
void crypto_aes_encrypt_x86(struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src) { aes_enc_blk(ctx, dst, src); }
static inline void enc(char *out, const char *in, aes_ctx *ctx) { if (aes_enc_blk((const unsigned char *)in, (unsigned char *)out, ctx) != aes_good) abort(); }
int encfile(FILE *fin, FILE *fout, aes_ctx *ctx, const char* ifn, const char* ofn) { char buf[BLOCK_LEN], dbuf[2 * BLOCK_LEN]; fpos_t flen; unsigned long i, len, rlen; // set a random IV fillrand(dbuf, BLOCK_LEN); // 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 <= BLOCK_LEN) { // if the file length is less than or equal to 16 bytes // read the bytes of the file into the buffer and verify length len = (unsigned long) fread(dbuf + BLOCK_LEN, 1, BLOCK_LEN, fin); rlen -= len; if(rlen > 0) return READ_ERROR; // pad the file bytes with zeroes for(i = len; i < BLOCK_LEN; ++i) dbuf[i + BLOCK_LEN] = 0; // xor the file bytes with the IV bytes for(i = 0; i < BLOCK_LEN; ++i) dbuf[i + BLOCK_LEN] ^= dbuf[i]; // encrypt the top 16 bytes of the buffer aes_enc_blk(dbuf + BLOCK_LEN, dbuf + len, ctx); len += BLOCK_LEN; // write the IV and the encrypted file bytes if(fwrite(dbuf, 1, len, fout) != len) return WRITE_ERROR; } else { // if the file length is more 16 bytes // write the IV if(fwrite(dbuf, 1, BLOCK_LEN, fout) != BLOCK_LEN) return WRITE_ERROR; // read the file a block at a time while(rlen > 0 && !feof(fin)) { // read a block and reduce the remaining byte count len = (unsigned long)fread(buf, 1, BLOCK_LEN, fin); rlen -= len; // verify length of block if(len != BLOCK_LEN) return READ_ERROR; // do CBC chaining prior to encryption for(i = 0; i < BLOCK_LEN; ++i) buf[i] ^= dbuf[i]; // encrypt the block aes_enc_blk(buf, dbuf, ctx); // if there is only one more block do ciphertext stealing if(rlen > 0 && rlen < BLOCK_LEN) { // move the previous ciphertext to top half of double buffer // since rlen bytes of this are output last for(i = 0; i < BLOCK_LEN; ++i) dbuf[i + BLOCK_LEN] = dbuf[i]; // read last part of plaintext into bottom half of buffer if(fread(dbuf, 1, rlen, fin) != rlen) return READ_ERROR; // clear the remainder of the bottom half of buffer for(i = 0; i < BLOCK_LEN - rlen; ++i) dbuf[rlen + i] = 0; // do CBC chaining from previous ciphertext for(i = 0; i < BLOCK_LEN; ++i) dbuf[i] ^= dbuf[i + BLOCK_LEN]; // encrypt the final block aes_enc_blk(dbuf, dbuf, ctx); // set the length of the final write len = rlen + BLOCK_LEN; rlen = 0; } // write the encrypted block if(fwrite(dbuf, 1, len, fout) != len) return WRITE_ERROR; } } return 0; }
ret_type CCM_init( const unsigned char key[], const unsigned long key_len, /* the key value to be used */ const unsigned char nonce[], /* the nonce value */ const unsigned char auth[], const unsigned long ad_len, /* the additional authenticated data */ const mlen_type msg_len, /* message data length */ const unsigned long auth_field_len, /* the authentication field length */ CCM_ctx ctx[1]) /* the CCM context */ { aes_32t cnt; if(aes_enc_key(key, key_len, ctx->aes) == aes_bad) return CCM_bad_key; /* bad key value */ if(auth_field_len < 2 || auth_field_len > 16 || (auth_field_len & 1)) return CCM_bad_auth_field_length; /* illegal authentication field size */ if(ad_len >= 65536ul - 256ul) return CCM_bad_auth_data_length; /* too much added authetication data */ /* save length values and compile the blocks for the running CBC and CTR values */ ctx->md_len = msg_len; ctx->af_len = auth_field_len; #ifndef LONG_MESSAGES ctx->blk[0] = (ctx->md_len & 0xff000000 ? 3 : ctx->md_len & 0xffff0000 ? 2 : 1); #else ctx->blk[0] = (ctx->md_len & 0xff00000000000000 ? 7 : ctx->md_len & 0xffff000000000000 ? 6 : ctx->md_len & 0xffffff0000000000 ? 5 : ctx->md_len & 0xffffffff00000000 ? 4 : ctx->md_len & 0xffffffffff000000 ? 3 : ctx->md_len & 0xffffffffffff0000 ? 2 : 1); #endif /* move the nonce into the block */ for(cnt = 0; cnt < (aes_32t)BLOCK_SIZE - ctx->blk[0] - 2; ++cnt) ctx->blk[cnt + 1] = nonce[cnt]; set_ctr(ctx, ctx->md_len); /* set message length value */ memcpy(ctx->cbc, ctx->blk, BLOCK_SIZE); /* and copy into running CBC */ ctx->cbc[0] |= (ad_len ? 0x40 : 0) + ((auth_field_len - 2) << 2); set_ctr(ctx, 1); /* initial counter value = 1 */ aes_enc_blk(ctx->cbc, ctx->cbc, ctx->aes); /* encrypt the cbc block */ aes_enc_blk(ctx->blk, ctx->sii, ctx->aes); /* encrypt counter block */ if(ad_len) /* if there is additional authentication data */ { cnt = 0; /* set the two byte length field for the data */ ctx->cbc[0] ^= (aes_08t)(ad_len >> 8); ctx->cbc[1] ^= (aes_08t) ad_len; while(cnt < ad_len) /* perform the CBC calculation on the data */ { /* xor data into the running CBC block */ ctx->cbc[(cnt + 2) & BLOCK_MASK] ^= auth[cnt]; /* if CBC block is full or at end of the authentication data */ if(!((++cnt + 2) & BLOCK_MASK) || cnt == ad_len) aes_enc_blk(ctx->cbc, ctx->cbc, ctx->aes); } } ctx->cnt = 0; return CCM_ok; }