krb5_error_code krb5int_aes_decrypt(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_dec_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) { if (input->length < BLOCK_SIZE) return KRB5_BAD_MSIZE; dec(output->data, input->data, &ctx); } else if (nblocks > 1) { for (blockno = 0; blockno < nblocks - 2; blockno++) { dec(tmp2, input->data + blockno * BLOCK_SIZE, &ctx); xorblock(tmp2, tmp); memcpy(output->data + blockno * BLOCK_SIZE, tmp2, BLOCK_SIZE); memcpy(tmp, input->data + blockno * BLOCK_SIZE, BLOCK_SIZE); } /* Do last two blocks, the second of which (next-to-last block of plaintext) may be incomplete. */ dec(tmp2, input->data + (nblocks - 2) * BLOCK_SIZE, &ctx); /* Set tmp3 to last ciphertext block, padded. */ memset(tmp3, 0, sizeof(tmp3)); memcpy(tmp3, input->data + (nblocks - 1) * BLOCK_SIZE, input->length - (nblocks - 1) * BLOCK_SIZE); /* Set tmp2 to last (possibly partial) plaintext block, and save it. */ xorblock(tmp2, tmp3); memcpy(output->data + (nblocks - 1) * BLOCK_SIZE, tmp2, input->length - (nblocks - 1) * BLOCK_SIZE); /* Maybe keep the trailing part, and copy in the last ciphertext block. */ memcpy(tmp2, tmp3, input->length - (nblocks - 1) * BLOCK_SIZE); /* Decrypt, to get next to last plaintext block xor previous ciphertext. */ dec(tmp3, tmp2, &ctx); xorblock(tmp3, tmp); memcpy(output->data + (nblocks - 2) * BLOCK_SIZE, tmp3, BLOCK_SIZE); if (ivec) memcpy(ivec->data, input->data + (nblocks - 2) * BLOCK_SIZE, 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"); }
BOOL Ckgb_arch_decompressDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. /*ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000);*/ /*CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } }*/ // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon //SetIcon(m_hIcon, TRUE); // Set small icon // TODO: Add extra initialization here lFiles.InsertColumn(0, loadString(IDS_FILE), LVCFMT_LEFT, 300); lFiles.InsertColumn(1, loadString(IDS_SIZE), LVCFMT_RIGHT, 100); char curDir[MAX_PATH]; GetCurrentDirectory(MAX_PATH, curDir); eDestination.SetWindowText(curDir); vector<string>files; vector<unsigned long>fsize; char arch[MAX_PATH]; HANDLE hProc = GetCurrentProcess(); HMODULE hMod; DWORD cbNeeded; EnumProcessModules(hProc, &hMod, sizeof(hMod), &cbNeeded); GetModuleFileNameEx(hProc, hMod, arch, MAX_PATH); //pierwszy modu³ jest aplikacj¹ //MessageBox(""); if(isSFXencrypted(arch)){ //wo³amy o has³o dlgPasswd dlgPass; if(dlgPass.DoModal() != IDOK){ theApp.ExitInstance(); return false; } strcpy(passwd, dlgPass._passwd); for(int i=strlen(passwd);i<32;i++) passwd[i] = '\0'; char arch2[MAX_PATH]; //strcpy(arch2, arch.c_str()); GetTempPath(MAX_PATH, arch2); GetLongPathName(arch2, arch2, sizeof(arch2)); strcat(arch2, "temp.kgb"); //arch2[strlen(arch2)-1] = 'b'; aes_ctx ctx[1]; ctx->n_rnd = 0; // ensure all flags are initially set to zero ctx->n_blk = 0; aes_dec_key((const unsigned char*)passwd, 32, ctx); /*CDialog dProgress; dProgress.Create(IDD_DECODING); dProgress.ShowWindow(SW_SHOW); dProgress.UpdateWindow();*/ FILE *fin = fopen(arch, "rb"); if(fin == 0) return false; fseek(fin, isSFXencrypted(arch), SEEK_SET); FILE *fout = fopen(arch2, "wb"); if(fout == 0) return false; decfile(fin, fout, ctx, arch, arch2); fclose(fin); fclose(fout); /*dProgress.ShowWindow(SW_HIDE); dProgress.~CDialog();*/ if(!checkArchiveFormat(arch2)){ _fcloseall(); DeleteFile(arch2); //eArchName.SetWindowText(""); MessageBox(loadString(IDS_WRONG_PASSWD), "KGB Archiver"); theApp.ExitInstance(); return false; } strcpy(arch, arch2); getFilesFromArchive(arch, files, fsize); }else{ getFilesFromArchive(arch, files, fsize); } strcpy(globalARCH, arch); //MessageBox(""); for(unsigned long i=0;i<files.size();i++){ char buffer[32]; /*if(filesizes[i] < 1024) sprintf(buffer, "%dB", filesizes[i]); else if(filesizes[i] < 1024*1024) sprintf(buffer, "%dKB", filesizes[i]/1024); else sprintf(buffer, "%dMB", filesizes[i]/1024/1024); */ sprintf(buffer, "%.1fKB", (double)fsize[i]/1024.0); lFiles.InsertItem(0, i, 0, 0, 0, 0, 0); lFiles.SetItemText(i, 0, files[i].c_str()); lFiles.SetItemText(i, 1, buffer); } //MessageBox(""); //delete curDir; /*char *cmd = theApp.m_lpCmdLine; char temp[MAX_PATH]; bool isArchName = true; /*sscanf(cmd, "-%c", &mode); switch(mode){ case 'c': cmd += 2; //przesówamy wskaŸnik* / for(unsigned long i=0;i<strlen(cmd);i++){ if(cmd[i] == '"'){ for(unsigned long j=0;i+j+1<strlen(cmd);j++){ if(cmd[i+j+1] != '"') temp[j] = cmd[i+j+1]; else if(cmd[i+j+1] == '"'){ temp[j] = 0; i += j+1; if(!isArchName) //lFiles.AddString(temp); eDestination.SetWindowText(temp); else{ eArchName.SetWindowText(temp); isArchName = false; } break; } } } }*/ //MessageBox(cmd); /*if(strlen(temp) == 0 || strlen(cmd) <= 2) return TRUE; vector<string> files; vector<unsigned long> filesizes; if(!getFilesFromArchive(temp, files, filesizes)){ MessageBox("Wybrany plik nie jest prawid³owym archiwum KGB!"); eArchName.SetWindowText(""); eDestination.SetWindowText(""); return TRUE; } //lFiles.DeleteAllItems(); for(unsigned long i=0;i<files.size();i++){ char buffer[32]; /*if(filesizes[i] < 1024) sprintf(buffer, "%dB", filesizes[i]); else if(filesizes[i] < 1024*1024) sprintf(buffer, "%dKB", filesizes[i]/1024); else sprintf(buffer, "%dMB", filesizes[i]/1024/1024); * / sprintf(buffer, "%.1fKB", (double)filesizes[i]/1024.0); lFiles.InsertItem(0, i, 0, 0, 0, 0, 0); lFiles.SetItemText(i, 0, files[i].c_str()); lFiles.SetItemText(i, 1, buffer); }*/ return TRUE; // return TRUE unless you set the focus to a control }
static krb5_error_code krb5int_aes_decrypt_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], tmp3[BLOCK_SIZE]; int nblocks = 0, blockno, i; size_t input_length; struct iov_block_state input_pos, output_pos; CHECK_SIZES; if (aes_dec_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); dec(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); dec(tmp2, blockN, &ctx); xorblock(tmp2, tmp); krb5int_c_iov_put_block(data, num_data, (unsigned char *)tmp2, BLOCK_SIZE, &output_pos); memcpy(tmp, blockN, BLOCK_SIZE); } /* Do last two blocks, the second of which (next-to-last block of plaintext) may be incomplete. */ /* First, get the last two encrypted 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); /* Decrypt second last block */ dec(tmp2, blockN2, &ctx); /* Set tmp2 to last (possibly partial) plaintext block, and save it. */ xorblock(tmp2, blockN1); memcpy(blockN2, tmp2, BLOCK_SIZE); /* Maybe keep the trailing part, and copy in the last ciphertext block. */ input_length %= BLOCK_SIZE; memcpy(tmp2, blockN1, input_length ? input_length : BLOCK_SIZE); dec(tmp3, tmp2, &ctx); xorblock(tmp3, tmp); /* Copy out ivec first before we clobber blockN1 with plaintext */ if (ivec != NULL) memcpy(ivec->data, blockN1, BLOCK_SIZE); memcpy(blockN1, tmp3, BLOCK_SIZE); /* Put the last two blocks back into the iovec */ 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); } return 0; }
krb5_error_code krb5int_aes_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { unsigned char tmp[BLOCK_SIZE], tmp2[BLOCK_SIZE], tmp3[BLOCK_SIZE]; int nblocks = 0, blockno; unsigned int i; size_t input_length; struct iov_block_state input_pos, output_pos; CHECK_SIZES; if (key->cache == NULL) { key->cache = malloc(sizeof(struct aes_key_info_cache)); if (key->cache == NULL) return ENOMEM; CACHE(key)->enc_ctx.n_rnd = CACHE(key)->dec_ctx.n_rnd = 0; } if (CACHE(key)->dec_ctx.n_rnd == 0) { if (aes_dec_key(key->keyblock.contents, key->keyblock.length, &CACHE(key)->dec_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(tmp, BLOCK_SIZE, data, num_data, &input_pos); dec(tmp2, tmp, &CACHE(key)->dec_ctx); krb5int_c_iov_put_block(data, num_data, tmp2, BLOCK_SIZE, &output_pos); } else if (nblocks > 1) { unsigned char blockN2[BLOCK_SIZE]; /* second last */ unsigned char blockN1[BLOCK_SIZE]; /* last block */ for (blockno = 0; blockno < nblocks - 2; blockno++) { unsigned char blockN[BLOCK_SIZE], *block; block = iov_next_block(blockN, BLOCK_SIZE, data, num_data, &input_pos); memcpy(tmp2, block, BLOCK_SIZE); dec(block, block, &CACHE(key)->dec_ctx); xorblock(block, tmp); memcpy(tmp, tmp2, BLOCK_SIZE); iov_store_block(data, num_data, block, blockN, BLOCK_SIZE, &output_pos); } /* Do last two blocks, the second of which (next-to-last block of plaintext) may be incomplete. */ /* First, get the last two encrypted blocks */ memset(blockN1, 0, sizeof(blockN1)); /* pad last block with zeros */ krb5int_c_iov_get_block(blockN2, BLOCK_SIZE, data, num_data, &input_pos); krb5int_c_iov_get_block(blockN1, BLOCK_SIZE, data, num_data, &input_pos); if (ivec != NULL) memcpy(ivec->data, blockN2, BLOCK_SIZE); /* Decrypt second last block */ dec(tmp2, blockN2, &CACHE(key)->dec_ctx); /* Set tmp2 to last (possibly partial) plaintext block, and save it. */ xorblock(tmp2, blockN1); memcpy(blockN2, tmp2, BLOCK_SIZE); /* Maybe keep the trailing part, and copy in the last ciphertext block. */ input_length %= BLOCK_SIZE; memcpy(tmp2, blockN1, input_length ? input_length : BLOCK_SIZE); dec(tmp3, tmp2, &CACHE(key)->dec_ctx); xorblock(tmp3, tmp); memcpy(blockN1, tmp3, BLOCK_SIZE); /* Put the last two blocks back into the iovec */ krb5int_c_iov_put_block(data, num_data, blockN1, BLOCK_SIZE, &output_pos); krb5int_c_iov_put_block(data, num_data, blockN2, BLOCK_SIZE, &output_pos); } 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; }