📄 milenage.java
字号:
package crypto_milenage;
import javacard.framework.* ;
public class milenage {
private final short block_size = (short)16;
public aes E ; // block cipher context
public byte [] SEQ = new byte[16];
public byte [] OP = new byte[16];
private byte [] OPC = new byte[16] ;
public byte [] K = new byte[16] ;
private final short off_OPC=(short)0;
public final static short SIZEBUF = (short)156; //(short)134;
public final static short MINSIZEBUF = (short)56 ;
public final static short off_hmac=(short)0 ;
public final static short off_prf =(short)56 ;
public final static short off_in=(short)0 ; //+16
public final static short off_out=(short)16 ; //+16
public final static short off_rand=(short)32 ; // +16
public final static short off_sqn= (short)48 ; // +6
public final static short off_amf= (short)54 ; // +2
public final static short off_mac=(short)56 ; //+16
public final static short off_res=(short)72 ; //+8
public final static short off_ck= (short)80 ; //+16
public final static short off_ik= (short)96 ; //+16
public final static short off_ak= (short)112 ; //+6
public final static short off_ak2=(short)118 ; //+6 (+10) -> 134
public final static short r1 = (128-64)/8; // f1
public final static short r2 = 0 ;
public final static short r3= (128-32)/8;
public final static short r4 = (128-64)/8; // f2f3f4
public final static short r5 = (128-96)/8;
public milenage()
{
}
public void ComputeOPc(byte [] buf,byte [] op, short off_op)
{short i;
E.encrypt(op,off_op,buf,off_in) ;
for (i=(short)0; i<(short)16; i++) buf[(short)(off_in+i)] ^= op[(short)(off_op+i)];
Util.arrayCopyNonAtomic(buf,off_in,OPC,off_OPC,(short)16);
return;
}
public void ComputeOPcRAND(byte [] buf,byte [] RAND, short off_RAND)
{short i;
for (i=0; i<16; i++)
buf[(short)(i+off_in)] = (byte) (RAND[(short)(i+off_RAND)] ^ OPC[(short)(i+off_OPC)]);
E.encrypt(buf,off_in,buf,off_rand);
return;
}
public void f1 (byte[] buf)
{ short i;
for(i=0;i<6;i++) buf[(short)(off_mac+i)]= buf[(short)(off_sqn+i)] ;
for(i=6;i<8;i++) buf[(short)(off_mac+i)]= buf[((short)(off_amf+i-6))] ;
for(i=8;i<14;i++) buf[(short)(off_mac+i)]= buf[(short)(off_sqn+i-8)] ;
for(i=14;i<16;i++) buf[(short)(off_mac+i)]= buf[(short)(off_amf+i-14)] ;
// System.out.println("SQN-AMF: " + openeapsmartcard.aaaConsole.cUtil.b2s(buf,off_mac,16));
/* XOR op_c and in1, rotate by r1=64, and XOR *
* on the constant c1 (which is all zeroes) */
for (i=0; i<16; i++)
buf[(short)(((i+r1)%16)+off_in)] = (byte)(buf[(short)(off_mac+i)] ^ OPC[(short)(off_OPC+i)]);
/* XOR on the value temp computed before */
for (i=0; i<16; i++)
buf[(short)(i+off_in)] = (byte) (buf[(short)(i+off_in)] ^ buf[(short)(i+off_rand)]);
E.encrypt(buf,off_in,buf,off_mac);
for (i=0; i<16; i++)
buf[(short)(i+off_mac)] = (byte) (buf[(short)(i+off_mac)] ^ OPC[(short)(i+off_OPC)]);
return;
} /* end of function f1(lsb)-f1*(msb) */
public void f1 (byte[] buf,byte[] MAC, short off_MAC)
{ short i;
for(i=0;i<6;i++) buf[(short)(off_out+i)]= buf[(short)(off_sqn+i)] ;
for(i=6;i<8;i++) buf[(short)(off_out+i)]= buf[((short)(off_amf+i-6))] ;
for(i=8;i<14;i++) buf[(short)(off_out+i)]= buf[(short)(off_sqn+i-8)] ;
for(i=14;i<16;i++) buf[(short)(off_out+i)]= buf[(short)(off_amf+i-14)] ;
/* XOR op_c and in1, rotate by r1=64, and XOR *
* on the constant c1 (which is all zeroes) */
for (i=0; i<16; i++)
buf[(short)(((i+r1)%16)+off_in)] = (byte)(buf[(short)(off_out+i)] ^ OPC[(short)(off_OPC+i)]);
/* XOR on the value temp computed before */
for (i=0; i<16; i++)
buf[(short)(i+off_in)] = (byte) (buf[(short)(i+off_in)] ^ buf[(short)(i+off_rand)]);
E.encrypt(buf,off_in,buf,off_out);
for (i=0; i<8; i++)
MAC[(short)(i+off_MAC)] = (byte) (buf[(short)(i+off_out)] ^ OPC[(short)(i+off_OPC)]);
return;
} /* end of function f1(lsb)-f1*(msb) */
public void f1star (byte[] buf,byte[] MAC, short off_MAC)
{ short i;
for(i=0;i<6;i++) buf[(short)(off_out+i)]= buf[(short)(off_sqn+i)] ;
for(i=6;i<8;i++) buf[(short)(off_out+i)]= buf[((short)(off_amf+i-6))] ;
for(i=8;i<14;i++) buf[(short)(off_out+i)]= buf[(short)(off_sqn+i-8)] ;
for(i=14;i<16;i++) buf[(short)(off_out+i)]= buf[(short)(off_amf+i-14)] ;
/* XOR op_c and in1, rotate by r1=64, and XOR *
* on the constant c1 (which is all zeroes) */
for (i=0; i<16; i++)
buf[(short)(((i+r1)%16)+off_in)] = (byte)(buf[(short)(off_out+i)] ^ OPC[(short)(off_OPC+i)]);
/* XOR on the value temp computed before */
for (i=0; i<16; i++)
buf[(short)(i+off_in)] = (byte) (buf[(short)(i+off_in)] ^ buf[(short)(i+off_rand)]);
E.encrypt(buf,off_in,buf,off_out);
for (i=0; i<8; i++)
MAC[(short)(i+off_MAC)] = (byte) (buf[(short)(i+off_out+8)] ^ OPC[(short)(i+off_OPC+8)]);
return;
} /* end of function f1(lsb)-f1*(msb) */
public void f2(byte[] buf, byte[] XRES, short off_XRES)
{ short i;
/* To obtain output block OUT2: XOR OPc and TEMP, *
* rotate by r2=0, and XOR on the constant c2 (which *
* is all zeroes except that the last bit is 1). */
for (i=0; i<16; i++)
buf[(short)(i+off_in)] = (byte) (buf[(short)(i+off_rand)] ^ OPC[(short)(i+off_OPC)]);
buf[(short)(15+off_in)] = (byte) (buf[(short)(15+off_in)] ^ (byte)1 );
E.encrypt(buf,off_in,buf,off_out);
for (i=0; i<8; i++)
XRES[(short)(i+off_XRES)] = (byte) (buf[(short)(8+i+off_out)] ^ OPC[(short)(8+i+off_OPC)]);
}
public void f3(byte[] buf, byte[] CK, short off_CK)
{ short i;
/* To obtain output block OUT3: XOR OPc and TEMP, *
* rotate by r3=32, and XOR on the constant c3 (which *
* is all zeroes except that the next to last bit is 1). */
for (i=0; i<16; i++)
buf[(short)(off_in+((i+r3)%16))] = (byte)(buf[(short)(off_rand+i)] ^ OPC[(short)(i+off_OPC)]);
buf[(short)(15+off_in)] = (byte) (buf[(short)(15+off_in)] ^ (byte)2 );
E.encrypt(buf,off_in,buf,off_out);
for (i=0; i<16; i++)
CK[(short)(off_CK+i)] = (byte)(buf[(short)(off_out+i)] ^ OPC[(short)(i+off_OPC)]);
}
public void f4(byte[] buf, byte[] IK, short off_IK)
{ short i;
/* To obtain output block OUT4: XOR OPc and TEMP, *
* rotate by r4=64, and XOR on the constant c4 (which *
* is all zeroes except that the 2nd from last bit is 1). */
for (i=0; i<16; i++)
buf[(short)(off_in+((i+r4) % 16))] = (byte)(buf[(short)(off_rand+i)] ^ OPC[(short)(i+off_OPC)]);
buf[(short)(15+off_in)] = (byte) (buf[(short)(15+off_in)] ^ (byte)4 );
E.encrypt(buf,off_in,buf,off_out);
for (i=0; i<16; i++)
IK[(short)(off_IK+i)] = (byte)(buf[(short)(off_out+i)] ^ OPC[(short)(i+off_OPC)]);
}
public void f5(byte[] buf, byte[] AK, short off_AK)
{ short i;
/* To obtain output block OUT2: XOR OPc and TEMP, *
* rotate by r2=0, and XOR on the constant c2 (which *
* is all zeroes except that the last bit is 1). */
for (i=0; i<16; i++)
buf[(short)(i+off_in)] = (byte) (buf[(short)(i+off_rand)] ^ OPC[(short)(i+off_OPC)]);
buf[(short)(15+off_in)] = (byte) (buf[(short)(15+off_in)] ^ (byte)1 );
E.encrypt(buf,off_in,buf,off_out);
for (i=0; i<6; i++)
AK[(short)(i+off_AK)] = (byte) (buf[(short)(i+off_out)] ^ OPC[(short)(i+off_OPC)]);
}
public void f5star(byte[] buf, byte[] AK2, short off_AK2)
{short i;
/* To obtain output block OUT5: XOR OPc and TEMP, *
* rotate by r5=96, and XOR on the constant c5 (which *
* is all zeroes except that the 3rd from last bit is 1). */
for (i=0; i<16; i++)
buf[(short)(off_in+((i+r5)%16))] = (byte)(buf[(short)(off_rand+i)] ^ OPC[(short)(i+off_OPC)]);
buf[(short)(15+off_in)] = (byte) (buf[(short)(15+off_in)] ^ (byte)8 );
E.encrypt(buf,off_in,buf,off_out);
for (i=0; i<6; i++)
AK2[(short)(off_AK2+i)] = (byte)(buf[(short)(off_out+i)] ^ OPC[(short)(i+off_OPC)]);
}
public void f2345 (byte[] buf)
{ byte i;
/* To obtain output block OUT2: XOR OPc and TEMP, *
* rotate by r2=0, and XOR on the constant c2 (which *
* is all zeroes except that the last bit is 1). */
for (i=0; i<16; i++)
buf[(short)(i+off_in)] = (byte) (buf[(short)(i+off_rand)] ^ OPC[(short)(i+off_OPC)]);
buf[(short)(15+off_in)] = (byte) (buf[(short)(15+off_in)] ^ (byte)1 );
E.encrypt(buf,off_in,buf,off_ck);
for (i=0; i<16; i++)
buf[(short)(i+off_ck)] = (byte) (buf[(short)(i+off_ck)] ^ OPC[(short)(i+off_OPC)]);
Util.arrayCopyNonAtomic(buf,off_ck,buf,off_ak,(short)6);
Util.arrayCopyNonAtomic(buf,(short)(off_ck+8),buf,off_res,(short)8);
/* To obtain output block OUT3: XOR OPc and TEMP, *
* rotate by r3=32, and XOR on the constant c3 (which *
* is all zeroes except that the next to last bit is 1). */
for (i=0; i<16; i++)
buf[(short)(off_in+((i+r3)%16))] = (byte)(buf[(short)(off_rand+i)] ^ OPC[(short)(i+off_OPC)]);
buf[(short)(15+off_in)] = (byte) (buf[(short)(15+off_in)] ^ (byte)2 );
E.encrypt(buf,off_in,buf,off_ck);
for (i=0; i<16; i++)
buf[(short)(off_ck+i)] = (byte)(buf[(short)(off_ck+i)] ^ OPC[(short)(i+off_OPC)]);
/* To obtain output block OUT4: XOR OPc and TEMP, *
* rotate by r4=64, and XOR on the constant c4 (which *
* is all zeroes except that the 2nd from last bit is 1). */
for (i=0; i<16; i++)
buf[(short)(off_in+((i+r4) % 16))] = (byte)(buf[(short)(off_rand+i)] ^ OPC[(short)(i+off_OPC)]);
buf[(short)(15+off_in)] = (byte) (buf[(short)(15+off_in)] ^ (byte)4 );
E.encrypt(buf,off_in,buf,off_ik);
for (i=0; i<16; i++)
buf[(short)(off_ik+i)] = (byte)(buf[(short)(off_ik+i)] ^ OPC[(short)(i+off_OPC)]);
return;
} /* end of function f2345 */
public void f5star(byte[] buf )
{
byte i;
/* To obtain output block OUT5: XOR OPc and TEMP, *
* rotate by r5=96, and XOR on the constant c5 (which *
* is all zeroes except that the 3rd from last bit is 1). */
for (i=0; i<16; i++)
buf[(short)(off_in+((i+r5)%16))] = (byte)(buf[(short)(off_rand+i)] ^ OPC[(short)(i+off_OPC)]);
buf[(short)(15+off_in)] = (byte) (buf[(short)(15+off_in)] ^ (byte)8 );
E.encrypt(buf,off_in,buf,off_ak2);
for (i=0; i<6; i++)
buf[(short)(off_ak2+i)] = (byte)(buf[(short)(off_ak2+i)] ^ OPC[(short)(i+off_OPC)]);
return;
} /* end of function f5star */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -