/* 'do it all in one go' subroutine */ void hmac_sha1(const unsigned char key[], unsigned int key_len, const unsigned char data[], unsigned int data_len, unsigned char mac[], unsigned int mac_len) { hmac_ctx cx[1]; hmac_sha1_begin(cx); hmac_sha1_key(key, key_len, cx); hmac_sha1_data(data, data_len, cx); hmac_sha1_end(mac, mac_len, cx); }
void Encrypt(PK0304* le, AE_EXTRA* ae, char* password) { char *salt, *key1, *key2, *check, digest[40]; u32 key_len = KeySize*2 + 2; u32 dig_len = 40; salt = BUF; key1 = salt+SaltSize; key2 = key1+KeySize; check = key2+KeySize; /* Gets a random salt (8-16 byte) */ sprng_read(salt, SaltSize, 0); /* Generates 2 keys for AES and HMAC, plus 2-byte password verification value */ if (pkcs_5_alg2(password, strlen(password), salt, SaltSize, 1000, 0, key1, &key_len) != CRYPT_OK) Z_ERROR("Failed to derive encryption keys"); // dump("salt", salt, SaltSize); // dump("key", key1, KeySize); if (ctr_start(0, IV, key1, KeySize, 0, CTR_COUNTER_LITTLE_ENDIAN, &ctr) != CRYPT_OK) Z_ERROR("Failed to setup AES CTR encoder"); #ifdef GLADMAN_HMAC hmac_sha1_begin(&hmac); hmac_sha1_key(key2, KeySize, &hmac); #else if (hmac_init(&hmac, 0, key2, KeySize) != CRYPT_OK) Z_ERROR("Failed to setup HMAC-SHA1"); #endif if (AE2) le->Crc32 = 0; le->Flag |= 1; le->CompMethod = 99; le->ExtraLen += 11; le->CompSize += SaltSize + 12; /* variable salt, fixed password check and hmac */ safeWrite(ZOUT, le, sizeof(PK0304)); fileCopy(ZOUT, ZIN, le->NameLen+le->ExtraLen-11); safeWrite(ZOUT, ae, 11); safeWrite(ZOUT, salt, SaltSize); safeWrite(ZOUT, check, 2); /* encrypt contents */ fileFilter(ZOUT, ZIN, le->CompSize-SaltSize-12); #ifdef GLADMAN_HMAC hmac_sha1_end(digest, dig_len, &hmac); #else if (hmac_done(&hmac, digest, &dig_len) != CRYPT_OK) Z_ERROR("Failed to computate HMAC"); #endif safeWrite(ZOUT, digest, 10); ctr_done(&ctr); }
void Decrypt(PK0304 *le, char *password) { char *salt, *key1, *key2, *check, digest[40]; u32 key_len, dig_len = 40, start, xlen; AE_EXTRA ae; start = ftell(ZIN); /* Searches for AE-1 header */ fseek(ZIN, le->NameLen, SEEK_CUR); for(xlen=le->ExtraLen; xlen;) { safeRead(&ae, ZIN, 4); xlen -= (4 + ae.Size); if (ae.Sig == 0x9901) { safeRead(&ae.Version, ZIN, 7); continue; } fseek(ZIN, ae.Size, SEEK_CUR); } if (ae.Sig != 0x9901) Z_ERROR("Fatal! Can't find AE extra header!"); if (ae.Strength < 1 || ae.Strength > 3) Z_ERROR("Bad encryption strength"); SaltSize = KS[ae.Strength].Salt; KeySize = KS[ae.Strength].Key; salt = BUF; key1 = salt+SaltSize; key2 = key1+KeySize; check = key2+KeySize; key_len = KeySize*2+2; /* Loads salt and password check value, and regenerates original crypto material */ fseek(ZIN, start+le->NameLen+le->ExtraLen, SEEK_SET); safeRead(salt, ZIN, SaltSize); safeRead(check+2, ZIN, 2); point1: if (pkcs_5_alg2(password, strlen(password), salt, SaltSize, 1000, 0, key1, &key_len) != CRYPT_OK) Z_ERROR("Failed to derive encryption keys"); if (memcmp(check, check+2, 2)) { printf("\nCan't decrypt data: try another password.\nNew password: "******"\n"); goto point1; } if (ctr_start(0, IV, key1, KeySize, 0, CTR_COUNTER_LITTLE_ENDIAN, &ctr) != CRYPT_OK) Z_ERROR("Failed to setup AES CTR decoder"); #ifdef GLADMAN_HMAC hmac_sha1_begin(&hmac); hmac_sha1_key(key2, KeySize, &hmac); #else if (hmac_init(&hmac, 0, key2, KeySize) != CRYPT_OK) Z_ERROR("Failed to setup HMAC-SHA1"); #endif /* Adjusts local header */ le->Flag ^= 1; le->CompMethod = ae.CompMethod; le->ExtraLen -= 11; le->CompSize -= (SaltSize + 12); /* Writes local header and copies extra, except 0x9901 */ safeWrite(ZOUT, le, sizeof(PK0304)); fseek(ZIN, start, SEEK_SET); fileCopy(ZOUT, ZIN, le->NameLen); for(xlen=le->ExtraLen+11; xlen;) { safeRead(&ae, ZIN, 4); xlen -= (4 + ae.Size); if (ae.Sig == 0x9901) { safeRead(&ae.Version, ZIN, 7); continue; } safeWrite(ZOUT, &ae, 4); fileCopy(ZOUT, ZIN, ae.Size); } fseek(ZIN, SaltSize+2, SEEK_CUR); fileFilter(ZOUT, ZIN, le->CompSize); #ifdef GLADMAN_HMAC hmac_sha1_end(digest, dig_len, &hmac); #else if (hmac_done(&hmac, digest, &dig_len) != CRYPT_OK) Z_ERROR("Failed to computate HMAC"); #endif /* Retrieves and checks HMACs */ safeRead(digest+10, ZIN, 10); if (memcmp(digest, digest+10, 10)) printf(" authentication failed, contents were lost!"); ctr_done(&ctr); }