System.arraycopy(uvs, 0, userKey, 32, 8);
System.arraycopy(uks, 0, userKey, 40, 8);
// Algorithm 3.8.2
md.update(userPassword, 0, Math.min(userPassword.length, 127));
md.update(uks);
AESCipherCBCnoPad ac = new AESCipherCBCnoPad(true, md.digest());
ueKey = ac.processBlock(key, 0, key.length);
// Algorithm 3.9.1
byte[] ovs = IVGenerator.getIV(8);
byte[] oks = IVGenerator.getIV(8);
md.update(ownerPassword, 0, Math.min(ownerPassword.length, 127));
md.update(ovs);
md.update(userKey);
ownerKey = new byte[48];
md.digest(ownerKey, 0, 32);
System.arraycopy(ovs, 0, ownerKey, 32, 8);
System.arraycopy(oks, 0, ownerKey, 40, 8);
// Algorithm 3.9.2
md.update(ownerPassword, 0, Math.min(ownerPassword.length, 127));
md.update(oks);
md.update(userKey);
ac = new AESCipherCBCnoPad(true, md.digest());
oeKey = ac.processBlock(key, 0, key.length);
// Algorithm 3.10
byte[] permsp = IVGenerator.getIV(16);
permsp[0] = (byte)permissions;
permsp[1] = (byte)(permissions >> 8);
permsp[2] = (byte)(permissions >> 16);
permsp[3] = (byte)(permissions >> 24);
permsp[4] = (byte)(255);
permsp[5] = (byte)(255);
permsp[6] = (byte)(255);
permsp[7] = (byte)(255);
permsp[8] = encryptMetadata ? (byte)'T' : (byte)'F';
permsp[9] = (byte)'a';
permsp[10] = (byte)'d';
permsp[11] = (byte)'b';
ac = new AESCipherCBCnoPad(true, key);
perms = ac.processBlock(permsp, 0, permsp.length);
}
catch (Exception ex) {
throw new ExceptionConverter(ex);
}
}