void aesCfbDecrypt(uint8_t *key, int32_t keyLength, uint8_t* IV, uint8_t *data, int32_t dataLength) { AESencrypt *saAes = new AESencrypt(); if (keyLength == 16) saAes->key128(key); else if (keyLength == 32) saAes->key256(key); else return; // Note: maybe copy IV to an internal array if we encounter strange things. // the cfb encrypt modify the IV on return. Same for output data (inplace encryption) saAes->cfb_decrypt(data, data, dataLength, IV); delete saAes; }
int32_t zina::aesCbcEncrypt(const string& key, const string& IV, const string& plainText, string* cryptText) { LOGGER(DEBUGGING, __func__, " -->"); if (IV.size() != AES_BLOCK_SIZE) { LOGGER(ERROR, __func__, " <-- IV wrong block size."); return WRONG_BLK_SIZE; } size_t padlen = (AES_BLOCK_SIZE - plainText.size() % AES_BLOCK_SIZE); // data.append(padlen, padlen); uint8_t* outBuffer = new uint8_t[plainText.size() + padlen]; memcpy(outBuffer, plainText.data(), plainText.size()); memset(outBuffer + plainText.size(), static_cast<int>(padlen&0xff), padlen); // pad to full blocksize uint8_t ivTemp[AES_BLOCK_SIZE]; // copy IV, AES code modifies IV buffer memcpy(ivTemp, IV.data(), AES_BLOCK_SIZE); AESencrypt aes; if (key.size() == 16) aes.key128((const uint8_t*)key.data()); else if (key.size() == 32) aes.key256((const uint8_t*)key.data()); else { LOGGER(ERROR, __func__, " <-- Unsupported key size: ", key.size()); delete[] outBuffer; return UNSUPPORTED_KEY_SIZE; } // Encrypt in place aes.cbc_encrypt(outBuffer, outBuffer, static_cast<int>(plainText.size() + padlen), ivTemp); cryptText->assign((const char*)outBuffer, plainText.size() + padlen); delete[] outBuffer; LOGGER(DEBUGGING, __func__, " <--"); return SUCCESS; }
void Sekrit::DoEncrypt(const Plaintext& plaintext) { const size_t roundedsize = util::roundup(plaintext.size(), aes_blocksize); assert(plaintext.size() <= std::numeric_limits<unsigned>::max()); assert(roundedsize <= std::numeric_limits<unsigned>::max()); m_impl->header.realsize = static_cast<unsigned>( plaintext.size() ); m_impl->header.size = static_cast<unsigned>( roundedsize ); m_impl->data.resize( m_impl->header.size ); // Fill CBC-mode InitializationVector with random bytes. Notice that we use // a "tempiv" and don't just work on header.iv, since cbc_encrypt works directly // on the buffer (which would leave us with a modified IV in the header - bad.) unsigned char tempiv[sizeof(m_impl->header.iv)]; util::fill_random( m_impl->header.iv, sizeof(m_impl->header.iv) ); memcpy(tempiv, m_impl->header.iv, sizeof(tempiv) ); AESencrypt crypt; crypt.key256(m_impl->key); crypt.cbc_encrypt(static_cast<unsigned char*>(plaintext.data()), &m_impl->data[0], m_impl->header.size, tempiv); }
int main(int argc, char *argv[]) { FILE *fdin, *fdout; unsigned char subkey[1024], buffer[4080]; char *workingDir, *chrBuf1, *chrBuf2, *outFile; int workingDirLen; CString SHASecret(""); unsigned char SHADigest[64]; unsigned char AESKey[24], backbuffer[16], backbuffer2[16], cryptbuf[16]; long filesize; int got, numcrypts, writesize; AESencrypt ct; long long totalbytes = 0; printEncIntro(); if (argc < 2) { encusage(argv[0]); return 0; } if (strstr(argv[1], "patch.zip")) { cerr << "the source file cannot be named patch.zip :P\n"; return -1; } chrBuf1 = strchr(argv[1], '\\'); if (chrBuf1 != NULL) { while (chrBuf1 != NULL) { chrBuf2 = chrBuf1; chrBuf1 = strchr(chrBuf1+1, '\\'); } workingDirLen = chrBuf2 - argv[1] + 1; workingDir = (char*)malloc(sizeof(char) * workingDirLen); strncpy(workingDir, argv[1], workingDirLen); outFile = (char*)malloc(sizeof(char) * workingDirLen + 10); strcpy(outFile, workingDir); strcpy(outFile+workingDirLen, "patch.zip"); outFile[workingDirLen+9] = '\0'; } else { outFile = "patch.zip"; } if ((fdin = fopen(argv[1], "rb")) == NULL) { cerr << "The source file could not be opened (typo?) :(\n"; return -1; } fseek(fdin, 0, SEEK_END); filesize = ftell(fdin); rewind(fdin); if ((fdout = fopen(outFile, "wb")) == NULL) { cerr << "The destination file could not be opened, this is bad :/\n"; return -1; } // first is first... fwrite("8O", 2, 1, fdout); // size of the plaintext zip file fwrite(&filesize, 4, 1, fdout); // size of the subkey, which we'll always make 1024 fwrite("\x00\x04\x00\x00", 4, 1, fdout); // generate subkey for (int i = 0; i < 1024; i++) subkey[i] = (unsigned char)rand(); // write actual subkey fwrite(subkey, 1024, 1, fdout); SHASecret.append((char*)subkey, 1024); SHASecret.append(patchkey, 47); SHA512_Simple(SHASecret.c_str(), 1071 /*1024 + 47*/, SHADigest); memcpy(AESKey, SHADigest, 24); ct.key(AESKey, 24); // verification block ct.encrypt(":DGROWBALLZPLEEZ",backbuffer2); fwrite(backbuffer2, 16, 1, fdout); got = fread(buffer, 1, 4080, fdin); do { printf("Encrypting %s: %d%% ", argv[1], (totalbytes * 100) / filesize); putchar(0x0d); numcrypts = (got / 16); if ((got % 16) > 0) { numcrypts++; filesize += got % 16; } writesize = numcrypts * 16; memset(backbuffer, '\0', 16); for (int j = 0; j < numcrypts; j++) { memcpy(backbuffer2, buffer+(j*16), 16); memcpy(cryptbuf, buffer+(j*16), 16); for (int i = 0; i < 16; i++) { cryptbuf[i] ^= (backbuffer[i] - i); } ct.encrypt(cryptbuf, buffer+(j*16)); memcpy(backbuffer, buffer+(j*16), 16); } fwrite(buffer, 1, writesize, fdout); totalbytes += writesize; got = fread(buffer, 1, 4080, fdin); } while (got > 0); cout << "Encrypting " << argv[1] << ": done\n"; fclose(fdin); fclose(fdout); return 0; }