Traditional PKWARE Encryptionの復号処理を書いてみる

データを処理してみないとなんとも。

#include <string.h>

#include "zlib.h"

void init_keys(uLong *keys) {
  keys[0] = 305419896L;
  keys[1] = 591751049L;
  keys[2] = 878082192L;
}

void update_keys(uLong *keys, char c) {
  keys[0] = crc32(keys[0], &c, 1);
  keys[1] = keys[1] + (keys[0] & 0xffL);
  keys[1] = keys[1] * 134775813L + 1L;
  c = (char) (keys[1] >> 24);
  keys[2] = crc32(keys[2], &c, 1);
}

unsigned char decrypt_byte(uLong *keys) {
  unsigned short temp;

  temp = (unsigned short) (keys[2] | 2L);
  return ((temp * (temp ^ 1)) >> 8);
}

void decrypt_header(char *buffer, uLong *keys) {
  int i;

  for (i = 0; i < 12; i++) {
    char c = buffer[i];
    c = buffer[i] ^ decrypt_byte(keys);
    update_keys(keys, c);
    buffer[i] = c;
  }
}

void decrypt_data(char *dest, const char *src, size_t n, uLong *keys) {
  int i;

  for (i = 0; i < n; i++) {
    char c = src[i];
    char temp = c ^ decrypt_byte(keys);
    update_keys(keys, temp);
    dest[i] = temp;
  }
}