}
// Implicit hash of data
byte[] origDataHash = md256.digest(data);
Rijndael aes;
try {
aes = new Rijndael(256, 256);
} catch (UnsupportedCipherException e) {
throw new Error("256/256 Rijndael not supported!");
}
// Encrypt data. Data encryption key = H(plaintext data).
aes.initialize(origDataHash);
PCFBMode pcfb = PCFBMode.create(aes, origDataHash);
pcfb.blockEncipher(data, 0, data.length);
byte[] encryptedDataHash = md256.digest(data);
// Create headers
byte[] headers = new byte[SSKBlock.TOTAL_HEADERS_LENGTH];
// First two bytes = hash ID
int x = 0;
headers[x++] = (byte) (KeyBlock.HASH_SHA256 >> 8);
headers[x++] = (byte) (KeyBlock.HASH_SHA256);
// Then crypto ID
headers[x++] = (byte) (Key.ALGO_AES_PCFB_256_SHA256 >> 8);
headers[x++] = Key.ALGO_AES_PCFB_256_SHA256;
// Then E(H(docname))
// Copy to headers
System.arraycopy(ehDocname, 0, headers, x, ehDocname.length);
x += ehDocname.length;
// Now the encrypted headers
byte[] encryptedHeaders = Arrays.copyOf(origDataHash, SSKBlock.ENCRYPTED_HEADERS_LENGTH);
int y = origDataHash.length;
short len = (short) compressedData.length;
if (asMetadata)
len |= 32768;
encryptedHeaders[y++] = (byte) (len >> 8);
encryptedHeaders[y++] = (byte) len;
encryptedHeaders[y++] = (byte) (compressionAlgo >> 8);
encryptedHeaders[y++] = (byte) compressionAlgo;
if (encryptedHeaders.length != y)
throw new IllegalStateException("Have more bytes to generate encoding SSK");
aes.initialize(cryptoKey);
pcfb.reset(ehDocname);
pcfb.blockEncipher(encryptedHeaders, 0, encryptedHeaders.length);
System.arraycopy(encryptedHeaders, 0, headers, x, encryptedHeaders.length);
x += encryptedHeaders.length;
// Generate implicit overall hash.