summaryrefslogtreecommitdiff
path: root/smccTest/src/main/java/at/gv/egiz/smcc/activation/RetailCBCMac.java
diff options
context:
space:
mode:
Diffstat (limited to 'smccTest/src/main/java/at/gv/egiz/smcc/activation/RetailCBCMac.java')
-rw-r--r--smccTest/src/main/java/at/gv/egiz/smcc/activation/RetailCBCMac.java186
1 files changed, 0 insertions, 186 deletions
diff --git a/smccTest/src/main/java/at/gv/egiz/smcc/activation/RetailCBCMac.java b/smccTest/src/main/java/at/gv/egiz/smcc/activation/RetailCBCMac.java
deleted file mode 100644
index 79f7be62..00000000
--- a/smccTest/src/main/java/at/gv/egiz/smcc/activation/RetailCBCMac.java
+++ /dev/null
@@ -1,186 +0,0 @@
-package at.gv.egiz.smcc.activation;
-
-import iaik.utils.CryptoUtils;
-
-import java.security.GeneralSecurityException;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-
-import javax.crypto.Cipher;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-
-public class RetailCBCMac {
-
- /**
- * Calculates a Retail CBC Mac from the given message.
- * <p>
- * The retail CBC Mac is calculated according to the following
- * algorithm:
- * <ul>
- * <li>
- * Pad the message to a multiple n of the CBC cipher block size with
- * a leading one bit followed by as many zero bits as necessary.
- * </li>
- * <li>
- * Create a CBC cipher key from the first <code>cbcCipherKeyLen</code>
- * bytes of the <code>csk</code> key and use it to calculate a
- * CBC Mac value from the first n-1 blocks of the padded message.
- * For CBC Mac calculation initialize the CBC Cipher with an
- * IV of all zero bytes.
- * </li>
- * <li>
- * XOR the last block of the padded message with the CBC mac value
- * and calculate the final retail MAC by encrypting the XOR result
- * with the given Cipher algorithm in ECB mode using no padding.
- * </li>
- * </ul>
- *
- * @param msg the message
- * @param cbcCipherAlg the name of the CBC Cipher algorithm to be used
- * @param cipherAlg the name of the final Cipher algorithm to be used
- * @param csk the secret key to be used
- * @param cbcCipherKeyLen the length of the CBC cipher key to be used
- * @param blockSize the block size of the CBC Cipher
- *
- * @return the retail CBC Mac value
- *
- * @throws NoSuchAlgorithmException if any of the requested Cipher algorithms
- * is not available
- * @throws NoSuchProviderException if the IAIK provider is not installed
- * @throws InvalidKeyException if the key cannot be used with the Ciphers
- * @throws GeneralSecurityException if the Cipher operation(s) fails
- */
- static byte[] retailMac(byte[] msg,
- String cbcCipherAlg,
- String cipherAlg,
- SecretKey csk,
- int cbcCipherKeyLen,
- int blockSize)
- throws NoSuchAlgorithmException,
- NoSuchProviderException,
- InvalidKeyException,
- GeneralSecurityException {
-
- if (msg == null) {
- throw new NullPointerException("Message m must not be null!");
- }
- if (csk == null) {
- throw new NullPointerException("Key csk must not be null!");
- }
-
- // calculate key for CBC cipher
- byte[] rawCsk = csk.getEncoded();
- int cskLen = rawCsk.length;
- SecretKey cbcCipherKey;
- if (cskLen == cbcCipherKeyLen) {
- cbcCipherKey = csk;
- } else if (cskLen < cbcCipherKeyLen) {
- throw new InvalidKeyException("Key too short!");
- } else {
- byte[] rawCbcCipherKey = new byte[blockSize];
- System.arraycopy(rawCsk, 0, rawCbcCipherKey, 0, blockSize);
- cbcCipherKey = new SecretKeySpec(rawCbcCipherKey, cbcCipherAlg);
- }
- // if necessary pad message with zeros
- byte[] paddedMsg = pad(msg, blockSize);
-
- // calculate CBC Mac for the first n-1 blocks
- int n = paddedMsg.length;
- int n_1 = n - blockSize;
- byte[] cbcMac = cbcMac(paddedMsg, 0, n_1, cbcCipherKey, cbcCipherAlg, blockSize);
-
- // calculate retail mac
- byte[] xor = new byte[blockSize];
- CryptoUtils.xorBlock(paddedMsg, n_1, cbcMac, 0, xor, 0, blockSize);
- Cipher cipher = Cipher.getInstance(cipherAlg+"/ECB/NoPadding", "IAIK");
- cipher.init(Cipher.ENCRYPT_MODE, csk);
- byte[] retailMac = cipher.doFinal(xor);
- return retailMac;
- }
-
- /**
- * Calculates a simple CBC Mac from the given (already) padded message.
- *
- * @param paddedMsg the (zero) padded message
- * @param off the start offset in the paddedMsg array
- * @param len the number of bytes to be processed, starting at <code>off</code>
- * @param key the Cipher key
- * @param cipherAlg the name of the CBC Cipher algorithm to be used
- * @param blockSize the block size of the CBC Cipher
- *
- * @return the CBC Mac value
- *
- * @throws NoSuchAlgorithmException if the requested Cipher algorithm
- * is not available
- * @throws NoSuchProviderException if the IAIK provider is not installed
- * @throws InvalidKeyException if the key cannot be used with the Ciphers
- * @throws GeneralSecurityException if the Cipher operation fails
- */
- static byte[] cbcMac(byte[] paddedMsg,
- int off,
- int len,
- SecretKey key,
- String cipherAlg,
- int blockSize)
- throws NoSuchAlgorithmException,
- NoSuchProviderException,
- InvalidKeyException,
- GeneralSecurityException {
-
- if (paddedMsg == null) {
- throw new NullPointerException("Message must not be null!");
- }
- if (key == null) {
- throw new NullPointerException("Key csk must not be null!");
- }
-
-
- Cipher cbcCipher = Cipher.getInstance(cipherAlg+"/CBC/NoPadding", "IAIK");
- byte[] iv = new byte[blockSize];
- cbcCipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
- int finOff = off;
- if (len > blockSize) {
- finOff = len - blockSize;
- cbcCipher.update(paddedMsg, 0, finOff);
- }
- byte[] mac = cbcCipher.doFinal(paddedMsg, finOff, blockSize);
- return mac;
- }
-
- /**
- * Pads the given message to a multiple of the given blocksize with
- * a leading one bit followed by as many zero bits as necessary
- *
- * @param msg the message to be padded
- * @param blockSize the block size
- *
- * @return the padded message
- */
- static byte[] pad(byte[] msg, int blockSize) {
- int paddingLen;
- byte[] paddedMsg;
-
- int msgLen = msg.length;
- if (msgLen == 0) {
- paddingLen = blockSize;
- } else {
- paddingLen = blockSize - msgLen % blockSize;
- }
- if (paddingLen > 0) {
- paddedMsg = new byte[msgLen + paddingLen];
- System.arraycopy(msg, 0, paddedMsg, 0, msgLen);
- paddedMsg[msgLen] = (byte)0x80;
- } else {
- paddedMsg = msg;
- }
- return paddedMsg;
- }
-
-
-
-
-
-}