krb5_error_code krb5int_aes_encrypt(const krb5_keyblock *key, const krb5_data *ivec, const krb5_data *input, krb5_data *output) { aes_ctx ctx; char tmp[BLOCK_SIZE], tmp2[BLOCK_SIZE], tmp3[BLOCK_SIZE]; int nblocks = 0, blockno; /* CHECK_SIZES; */ if (aes_enc_key(key->contents, key->length, &ctx) != aes_good) abort(); if (ivec) memcpy(tmp, ivec->data, BLOCK_SIZE); else memset(tmp, 0, BLOCK_SIZE); nblocks = (input->length + BLOCK_SIZE - 1) / BLOCK_SIZE; if (nblocks == 1) { /* Used when deriving keys. */ if (input->length < BLOCK_SIZE) return KRB5_BAD_MSIZE; enc(output->data, input->data, &ctx); } else if (nblocks > 1) { unsigned int nleft; for (blockno = 0; blockno < nblocks - 2; blockno++) { xorblock(tmp, input->data + blockno * BLOCK_SIZE); enc(tmp2, tmp, &ctx); memcpy(output->data + blockno * BLOCK_SIZE, tmp2, BLOCK_SIZE); /* Set up for next block. */ memcpy(tmp, tmp2, BLOCK_SIZE); } /* Do final CTS step for last two blocks (the second of which may or may not be incomplete). */ xorblock(tmp, input->data + (nblocks - 2) * BLOCK_SIZE); enc(tmp2, tmp, &ctx); nleft = input->length - (nblocks - 1) * BLOCK_SIZE; memcpy(output->data + (nblocks - 1) * BLOCK_SIZE, tmp2, nleft); memcpy(tmp, tmp2, BLOCK_SIZE); memset(tmp3, 0, sizeof(tmp3)); memcpy(tmp3, input->data + (nblocks - 1) * BLOCK_SIZE, nleft); xorblock(tmp, tmp3); enc(tmp2, tmp, &ctx); memcpy(output->data + (nblocks - 2) * BLOCK_SIZE, tmp2, BLOCK_SIZE); if (ivec) memcpy(ivec->data, tmp2, BLOCK_SIZE); } return 0; }
//设置加密密钥 BOOL CEncrypt::SetEncryptKey(const char* szEncryKey, uint16_t nKeyLen) { assert(szEncryKey); assert(nKeyLen >= MIN_ENCRYPT_KEY_SIZE); if(NULL == szEncryKey || nKeyLen < MIN_ENCRYPT_KEY_SIZE) return FALSE; rc6_set_key((unsigned long *)szEncryKey, nKeyLen*8, &m_stRc6Ctx); aes_enc_key((unsigned char *)szEncryKey, nKeyLen, &m_stAesEncryCtx); aes_dec_key((unsigned char *)szEncryKey, nKeyLen, &m_stAesDecryCtx); return TRUE; }
static void init () { unsigned int i, j, r; srand(42); for (i = 0; i < 16; i++) key[i] = 0xff & rand(); memset(test_case, 0, sizeof(test_case)); for (i = 0; i < NTESTS; i++) for (j = 0; j < test_case_len[i]; j++) { test_case[i].input[j] = 0xff & rand(); } r = aes_enc_key (key, sizeof(key), &ctx); if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); r = aes_dec_key (key, sizeof(key), &dctx); if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); }
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 krb5_error_code krb5int_aes_encrypt_iov(const krb5_keyblock *key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { aes_ctx ctx; char tmp[BLOCK_SIZE], tmp2[BLOCK_SIZE]; int nblocks = 0, blockno; size_t input_length, i; struct iov_block_state input_pos, output_pos; if (aes_enc_key(key->contents, key->length, &ctx) != aes_good) abort(); if (ivec != NULL) memcpy(tmp, ivec->data, BLOCK_SIZE); else memset(tmp, 0, BLOCK_SIZE); for (i = 0, input_length = 0; i < num_data; i++) { krb5_crypto_iov *iov = &data[i]; if (ENCRYPT_IOV(iov)) input_length += iov->data.length; } IOV_BLOCK_STATE_INIT(&input_pos); IOV_BLOCK_STATE_INIT(&output_pos); nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE; if (nblocks == 1) { krb5int_c_iov_get_block((unsigned char *)tmp, BLOCK_SIZE, data, num_data, &input_pos); enc(tmp2, tmp, &ctx); krb5int_c_iov_put_block(data, num_data, (unsigned char *)tmp2, BLOCK_SIZE, &output_pos); } else if (nblocks > 1) { char blockN2[BLOCK_SIZE]; /* second last */ char blockN1[BLOCK_SIZE]; /* last block */ for (blockno = 0; blockno < nblocks - 2; blockno++) { char blockN[BLOCK_SIZE]; krb5int_c_iov_get_block((unsigned char *)blockN, BLOCK_SIZE, data, num_data, &input_pos); xorblock(tmp, blockN); enc(tmp2, tmp, &ctx); krb5int_c_iov_put_block(data, num_data, (unsigned char *)tmp2, BLOCK_SIZE, &output_pos); /* Set up for next block. */ memcpy(tmp, tmp2, BLOCK_SIZE); } /* Do final CTS step for last two blocks (the second of which may or may not be incomplete). */ /* First, get the last two blocks */ memset(blockN1, 0, sizeof(blockN1)); /* pad last block with zeros */ krb5int_c_iov_get_block((unsigned char *)blockN2, BLOCK_SIZE, data, num_data, &input_pos); krb5int_c_iov_get_block((unsigned char *)blockN1, BLOCK_SIZE, data, num_data, &input_pos); /* Encrypt second last block */ xorblock(tmp, blockN2); enc(tmp2, tmp, &ctx); memcpy(blockN2, tmp2, BLOCK_SIZE); /* blockN2 now contains first block */ memcpy(tmp, tmp2, BLOCK_SIZE); /* Encrypt last block */ xorblock(tmp, blockN1); enc(tmp2, tmp, &ctx); memcpy(blockN1, tmp2, BLOCK_SIZE); /* Put the last two blocks back into the iovec (reverse order) */ krb5int_c_iov_put_block(data, num_data, (unsigned char *)blockN1, BLOCK_SIZE, &output_pos); krb5int_c_iov_put_block(data, num_data, (unsigned char *)blockN2, BLOCK_SIZE, &output_pos); if (ivec != NULL) memcpy(ivec->data, blockN1, BLOCK_SIZE); } return 0; }
int main(int argc, char *argv[]) { FILE *fin = 0, *fout = 0; char *cp, ch, key[32]; int i, by, key_len, err = 0; aes_ctx ctx[1]; if(argc != 5 || toupper(*argv[3]) != 'D' && toupper(*argv[3]) != 'E') { printf("usage: aesxam in_filename out_filename [d/e] key_in_hex\n"); err = -1; goto exit; } ctx->n_rnd = 0; // ensure all flags are initially set to zero ctx->n_blk = 0; cp = argv[4]; // this is a pointer to the hexadecimal key digits i = 0; // this is a count for the input digits processed while(i < 64 && *cp) // the maximum key length is 32 bytes and { // hence at most 64 hexadecimal digits ch = toupper(*cp++); // process a hexadecimal digit if(ch >= '0' && ch <= '9') by = (by << 4) + ch - '0'; else if(ch >= 'A' && ch <= 'F') by = (by << 4) + ch - 'A' + 10; else // error if not hexadecimal { printf("key must be in hexadecimal notation\n"); err = -2; goto exit; } // store a key byte for each pair of hexadecimal digits if(i++ & 1) key[i / 2 - 1] = by & 0xff; } if(*cp) { printf("The key value is too long\n"); err = -3; goto exit; } else if(i < 32 || (i & 15)) { printf("The key length must be 32, 48 or 64 hexadecimal digits\n"); err = -4; goto exit; } key_len = i / 2; if(!(fin = fopen(argv[1], "rb"))) // try to open the input file { printf("The input file: %s could not be opened\n", argv[1]); err = -5; goto exit; } if(!(fout = fopen(argv[2], "wb"))) // try to open the output file { printf("The input file: %s could not be opened\n", argv[1]); err = -6; goto exit; } if(toupper(*argv[3]) == 'E') // encryption in Cipher Block Chaining mode { aes_enc_key(key, key_len, ctx); err = encfile(fin, fout, ctx, argv[1], argv[2]); } else // decryption in Cipher Block Chaining mode { aes_dec_key(key, key_len, ctx); err = decfile(fin, fout, ctx, argv[1], argv[2]); } exit: if(err == READ_ERROR) printf("Error reading from input file: %s\n", argv[1]); if(err == WRITE_ERROR) printf("Error writing to output file: %s\n", argv[2]); if(fout) fclose(fout); if(fin) fclose(fin); return err; }
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; }