Compare commits

...

30 Commits

Author SHA1 Message Date
zcy
a8b47e8df6 Merge pull request '移除无用文件' (#3) from zcy_dev_cap into main
Reviewed-on: https://59.110.142.199:3333/qzh/se-algo/pulls/3
2025-09-09 02:41:23 +00:00
zcy
7425c4d980 移除无用文件 2025-09-09 10:41:02 +08:00
zcy
8bbdc5259e Merge pull request '位置加密applet基本实现,目录下包含c java参考代码、打包工具、说明文档、' (#2) from zcy_dev_cap into main
Reviewed-on: https://59.110.142.199:3333/qzh/se-algo/pulls/2
2025-09-09 02:39:34 +00:00
zcy
088c0c00f6 调整目录结构 2025-09-09 10:36:33 +08:00
zcy
2549f565b4 密钥存储flash空间80->120,写调用说明 2025-09-09 09:49:57 +08:00
zcy
2f79d18966 初始化位置添加了25B iv 到23B iv的转换 2025-09-09 02:59:55 +08:00
zcy
7f529c4bd2 Zuc256算法验证完毕,applet中测试加解密38字节文本成功;位置加密调用zuc256算法,返回值符合预期,与样例程序一致。 2025-09-09 02:49:59 +08:00
zcy
9405e59ac9 在method里面统一定义缓存变量 2025-09-09 02:36:40 +08:00
zcy
dec1fecc16 在method里面统一定义缓存变量,所有函数全塞到一起,大小驼峰下划线全大写变量名混用 2025-09-09 01:30:35 +08:00
zcy
fe4e0ff4e6 new对象(short、byte数组)改为调用JCSystem.makeTransientXxxArray放到ram里面;
makeTransientXxxArray类型改为MEMORY_TYPE_TRANSIENT_RESETMEMORY_TYPE_TRANSIENT_RESET
2025-09-09 00:08:11 +08:00
zcy
8e25aab97a new对象(short、byte数组)改为调用JCSystem.makeTransientXxxArray放到ram里面;
makeTransientXxxArray类型改为MEMORY_TYPE_TRANSIENT_RESETMEMORY_TYPE_TRANSIENT_RESET
2025-09-09 00:04:54 +08:00
zcy
5456e990e6 输入80E3,可执行算法正确性检验,验证通过,对len=38Bytes明文加密结果符合预期、解密结果符合输入;
输入80E2,可写入密钥到flash,若算法类型、key id, key版本一致,就写入,已满就报错,无记录就写入新记录;
输入80CA,可执行伪位置加密,原封不动将输入的data返回回来。
2025-09-08 23:46:46 +08:00
zcy
b41fff9d09 临时存储 2025-09-08 15:35:28 +08:00
zcy
98d411d70d 临时存储 2025-09-08 13:28:19 +08:00
zcy
ed52d849a4 写基础Applet,试图测试加解密正确性 2025-09-05 22:47:16 +08:00
zcy
a74ab6f212 core enc util 全部转为javacard写法 2025-09-05 20:14:55 +08:00
zcy
57b385aaa2 reset zuc enc 2025-09-05 17:34:21 +08:00
zcy
4dcf92584c Merge remote-tracking branch 'origin/main' into zcy_dev_cap
# Conflicts:
#	Project/Src/com/cscn/Zuc256EncryptCtx.java
#	Project/Src/com/cscn/Zuc256Tables.java
#	src/com/zuc/zuc256/Zuc256MacCtx.java
#	src/com/zuc/zuc256/Zuc256State.java
2025-09-05 17:20:38 +08:00
qzh
8893172ea9 适配card short类型,取消int long 2025-09-05 16:40:12 +08:00
zcy
b331864cee Zuc256Util int运算改short 2025-09-05 16:25:32 +08:00
zcy
747ac56a68 移植中 2025-09-05 15:55:46 +08:00
zcy
2310d0aca1 初始化 2025-09-05 15:16:21 +08:00
zcy
e8b2fa9c65 初始化 2025-09-05 15:15:33 +08:00
zcy
5122f8eade gradle+jcdk 构建最精简applet 2025-09-03 20:57:53 +08:00
zcy
11c46c5557 Merge pull request 'zcy_dev 将单文件ZUC256拆分为多文件,并封装init update final 方法' (#1) from zcy_dev into main
Reviewed-on: https://59.110.142.199:3333/qzh/se-algo/pulls/1
2025-09-03 09:09:06 +00:00
zcy
80b02f6139 调整注释和readme 2025-09-03 17:06:28 +08:00
zcy
55332f6b3f 调整注释和readme 2025-09-03 17:00:14 +08:00
zcy
8880f2065e 将单文件ZUC256拆分为多文件,并封装init update final 方法 2025-09-03 16:54:32 +08:00
zcy
1b4c192180 框架初始化 2025-09-03 15:40:10 +08:00
qzh
176b0aa6f6 add java zuc256 2025-09-03 15:12:39 +08:00
778 changed files with 27887 additions and 184 deletions

6
.gitignore vendored
View File

@@ -2,3 +2,9 @@ build
__pycache__
.sconsign.dblite
.vscode
*.class
/out/
/.gradle/
/.idea/
/Project/bin/
/se-algo.iml

18
LICENSE
View File

@@ -1,18 +0,0 @@
MIT License
Copyright (c) 2025 gj
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.

152
README.md
View File

@@ -10,3 +10,155 @@
sudo apt-get install scons
sudo apt-get install build-essential
```
---
0909 位置加密applet调用说明
1. E2 密钥存储接口
说明:
密钥长度为16或32B加上密钥信息(4B)最多36B按每个密钥40B存储在flash中。目前共分配了120B空间。可存3个密钥
遇相同(算法类型, 密钥ID, 密钥版本)密钥,覆盖存储;
新密钥存储在新空间;
密钥长度超长会报错,空间满会报错。
返回A1+5字节密文+9000
样例1
存储一个长度16算法A1id01version02的Key[1122..FF00]
80 E2 00 01 14
13 A1 01 02 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF 00
/send 80E200011413A10102112233445566778899AABBCCDDEEFF00
->
90 00
样例2
存储一个长度32算法A2id02version02的Key[0102..1F20]
80 E2 00 02 24
23 A2 02 02
01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10
11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20
/send 80E200022423A202020102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20
->
90 00
样例3
存储一个长度FF算法A2id02version02的Key[0102..1F20]
80 E2 00 02 24
FF A2 02 02
01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10
11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20
/send 80E2000224FFA202020102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20
->
69 84 (超长 FF)
样例4
存储一个长度32算法A2id01version02的Key[0102..1F20]
80 E2 00 02 24
23 A2 01 02
01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10
11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20
/send 80E200022423A202020102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20
->
90 00
样例4
存储一个长度16算法A3id02version02的Key[0102..0F10],执行后空间满 120B
80 E2 00 02 14
13 A3 02 02
01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10
/send 80E200021413A302020102030405060708090A0B0C0D0E0F10
->
90 00
样例5
存储一个长度16算法A3id09version02的Key[0102..0F10]
80 E2 00 02 14
13 A3 09 02
01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10
/send 80E200021413A309020102030405060708090A0B0C0D0E0F10
->
6A 84 空间满
样例6
存储一个长度16算法A2id02version02的Key[0102..0F10](覆盖样例3空间)
80 E2 00 02 14
13 A2 02 02
01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10
/send 80E200021413A202020102030405060708090A0B0C0D0E0F10
->
90 00
--------
2. CA 位置加密
数据为1字节随机数6字节STMSI5字节数据
目前随机数和STMSI未使用此接口用固定Key IV对数据进行Zuc256加密返回加密后数据。
// Key: 32字节
private static final byte[] KEY32 = {
(byte)0x30,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,(byte)0x35,(byte)0x36,(byte)0x37,
(byte)0x38,(byte)0x39,(byte)0x61,(byte)0x62,(byte)0x63,(byte)0x64,(byte)0x65,(byte)0x66,
(byte)0x30,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,(byte)0x35,(byte)0x36,(byte)0x37,
(byte)0x38,(byte)0x39,(byte)0x61,(byte)0x62,(byte)0x63,(byte)0x64,(byte)0x65,(byte)0x66
};
// IV: 25字节
private static final byte[] IV25 = {
(byte)0x30,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,(byte)0x35,(byte)0x36,(byte)0x37,
(byte)0x38,(byte)0x39,(byte)0x61,(byte)0x62,(byte)0x63,(byte)0x64,(byte)0x65,(byte)0x66,
(byte)0x67,(byte)0x30,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,(byte)0x35,(byte)0x36,
(byte)0x37
};
样例1
80 CA 00 00 0E
A1 0C 00 11 22 33 44 55 66 AA BB CC DD EE
/send 80CA00000EA10C00112233445566AABBCCDDEE
->
A1 06 01 9C 00 B3 15 05 90 00
样例2
80 CA 00 00 0E
A1 0C 00 11 22 33 44 55 66 FF 00 FF 00 FF
/send 80CA00000EA10C00112233445566FF00FF00FF
->
A1 06 01 C9 BB 80 C8 14 90 00
样例3
80 CA 00 00 0E
A1 0C 00 11 22 33 44 55 66 31 32 33 34 35
/send 80CA00000EA10C001122334455663132333435
->
A1 06 01 07 89 4C FC DE 90 00
---
# com.zuc.zuc256代码结构说明
```
com.zuc.zuc256:
Zuc256Tables.java算法常量S 盒、D 数组)。
Zuc256State.java内部状态LFSR、R1、R2
Zuc256Util.java工具方法整数转换、位运算、线性变换、调试输出
Zuc256Core.java算法核心初始化、密钥字生成、密钥流生成
Zuc256EncryptCtx.java加解密上下文。
Zuc256MacCtx.javaMAC上下文。
Zuc256Demo.java演示程序明文加密、解密与结果验证
```
---

View File

@@ -1,40 +0,0 @@
import os
from SCons.Script import *
# 导入环境
Import('env')
# 项目根目录
CWD = os.getcwd()
# 收集源码(.c 和 .S 文件)
sources = Glob(os.path.join(CWD, 'src/*.c')) + Glob(os.path.join(CWD, 'src/*.S'))
# 编译选项
cpppath = [
CWD,
os.path.join(CWD, 'inc'), # 仅使用项目内的头文件目录
]
# 确保 build 目录存在
BUILD_DIR = 'build'
if not os.path.exists(BUILD_DIR):
os.makedirs(BUILD_DIR)
# 逐个编译源码生成目标文件(输出到 build 目录)
objs = []
for src in sources:
src_path = str(src) # 转换为字符串路径
obj_name = os.path.basename(src_path).replace('.c', '.o').replace('.S', '.o')
obj_path = os.path.join(CWD, BUILD_DIR, obj_name)
obj = env.Object(
target=obj_path,
source=src_path,
CPPPATH=cpppath,
)
objs.append(obj)
# 返回目标文件列表,给 SConstruct 链接用
Return('objs')

View File

@@ -1,47 +0,0 @@
import os
from SCons.Script import *
# 确保 build 目录存在
BUILD_DIR = 'build'
if not os.path.exists(BUILD_DIR):
os.makedirs(BUILD_DIR)
# 导入配置(修改为导入algo.py)
from algo import *
# 初始化构建环境
env = Environment(
tools=['default'],
CC=CC,
CXX=CXX,
AS=AS,
AR=AR,
LINK=LINK,
CCFLAGS=CFLAGS,
CXXFLAGS=CFLAGS,
ASFLAGS=AFLAGS,
LINKFLAGS=LFLAGS,
CPPPATH=['inc'], # 仅使用项目内的头文件目录
)
# 递归构建源码(SConscript 负责收集编译文件)
src_objs = env.SConscript('SConscript', exports='env')
# 链接生成 elf 文件(输出到 build 目录)
elf_target = os.path.join(BUILD_DIR, TARGET_NAME)
elf_file = env.Program(elf_target, src_objs)
# 后处理:生成 bin、asm 等文件
post_commands = env.Command(
os.path.join(BUILD_DIR, 'post_actions'), # 虚拟目标,确保命令执行
elf_file,
POST_ACTION
)
# 关联默认构建目标(执行 scons 时默认编译+后处理)
Default(elf_file)
Default(post_commands)
# 清理规则(删除 build 目录及内容)
Clean(elf_file, BUILD_DIR)

1586
Src/com/cscn/Method.java Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,97 @@
package com.cscn;
import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
/**
* @author liuww
*
*/
public class XwSecurity extends Applet {
//todo test
public static final byte INS_PROCESS_DATA_TEST = (byte)0xE3;
public static final byte INS_LOCATION_ENCRYPT = (byte)0xCA;
public static final byte INS_STORE_KEY = (byte)0xE2;
// public static final byte INS_INITIAL_UPDATE = (byte)0x50;
//
// public static final byte INS_EXTERNAL_AUTH = (byte)0x82;
private Method method;
byte[] key_store_byte;
public XwSecurity(byte[] bArray, short bOffset, byte bLength) {
// TODO Auto-generated constructor stub
method = new Method(); //todo new?
// key store -> flash
key_store_byte = new byte[120];
register(bArray, (short)(bOffset + 1), bArray[bOffset]);
}
public static void install(byte[] bArray, short bOffset, byte bLength)
{
//todo new?
// GP-compliant JavaCard applet registration
new XwSecurity(bArray, bOffset, bLength);
}
public void process(APDU apdu)
{
// Good practice: Return 9000 on SELECT
if(selectingApplet())
{
return;
}
if(method == null) {
return;
}
byte[] buf = apdu.getBuffer();
short off = ISO7816.OFFSET_CDATA;
short len = apdu.setIncomingAndReceive();
switch (buf[ISO7816.OFFSET_INS])
{
// case INS_INITIAL_UPDATE:
// SecureChannel sc = GPSystem.getSecureChannel();
// sc.processSecurity(apdu);
// break;
//
// case INS_EXTERNAL_AUTH:
// sc = GPSystem.getSecureChannel();
// sc.processSecurity(apdu);
// break;
//todo test
case INS_PROCESS_DATA_TEST:
method.testZuc256(apdu);
break;
case INS_LOCATION_ENCRYPT:
len = method.locationEncryptZuc(buf, off, len, key_store_byte);
apdu.setOutgoingAndSend(off, len);
break;
case INS_STORE_KEY:
len = method.updateKey(buf, off, len, key_store_byte);
apdu.setOutgoingAndSend(off, len);
break;
default:
// good practice: If you don't know the INStruction, say so:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
}

View File

@@ -0,0 +1,98 @@
package com.cscn;
/**
* 常量表S0/S1 与 ZUC256_D。
* 注意JavaCard 目标环境建议将表定义为 static final 数组,按 int/short 存放。
* 适配说明:已将 32bit int 数组改为 16bit short 数组符合JavaCard 16bit能力要求
*/
public final class Zuc256Tables {
// 私有构造函数:防止类被实例化
private Zuc256Tables() {}
// S盒S0, S1
public static final short[] S0 = {
0x3e,0x72,0x5b,0x47,0xca,0xe0,0x00,0x33,0x04,0xd1,0x54,0x98,0x09,0xb9,0x6d,0xcb,
0x7b,0x1b,0xf9,0x32,0xaf,0x9d,0x6a,0xa5,0xb8,0x2d,0xfc,0x1d,0x08,0x53,0x03,0x90,
0x4d,0x4e,0x84,0x99,0xe4,0xce,0xd9,0x91,0xdd,0xb6,0x85,0x48,0x8b,0x29,0x6e,0xac,
0xcd,0xc1,0xf8,0x1e,0x73,0x43,0x69,0xc6,0xb5,0xbd,0xfd,0x39,0x63,0x20,0xd4,0x38,
0x76,0x7d,0xb2,0xa7,0xcf,0xed,0x57,0xc5,0xf3,0x2c,0xbb,0x14,0x21,0x06,0x55,0x9b,
0xe3,0xef,0x5e,0x31,0x4f,0x7f,0x5a,0xa4,0x0d,0x82,0x51,0x49,0x5f,0xba,0x58,0x1c,
0x4a,0x16,0xd5,0x17,0xa8,0x92,0x24,0x1f,0x8c,0xff,0xd8,0xae,0x2e,0x01,0xd3,0xad,
0x3b,0x4b,0xda,0x46,0xeb,0xc9,0xde,0x9a,0x8f,0x87,0xd7,0x3a,0x80,0x6f,0x2f,0xc8,
0xb1,0xb4,0x37,0xf7,0x0a,0x22,0x13,0x28,0x7c,0xcc,0x3c,0x89,0xc7,0xc3,0x96,0x56,
0x07,0xbf,0x7e,0xf0,0x0b,0x2b,0x97,0x52,0x35,0x41,0x79,0x61,0xa6,0x4c,0x10,0xfe,
0xbc,0x26,0x95,0x88,0x8a,0xb0,0xa3,0xfb,0xc0,0x18,0x94,0xf2,0xe1,0xe5,0xe9,0x5d,
0xd0,0xdc,0x11,0x66,0x64,0x5c,0xec,0x59,0x42,0x75,0x12,0xf5,0x74,0x9c,0xaa,0x23,
0x0e,0x86,0xab,0xbe,0x2a,0x02,0xe7,0x67,0xe6,0x44,0xa2,0x6c,0xc2,0x93,0x9f,0xf1,
0xf6,0xfa,0x36,0xd2,0x50,0x68,0x9e,0x62,0x71,0x15,0x3d,0xd6,0x40,0xc4,0xe2,0x0f,
0x8e,0x83,0x77,0x6b,0x25,0x05,0x3f,0x0c,0x30,0xea,0x70,0xb7,0xa1,0xe8,0xa9,0x65,
0x8d,0x27,0x1a,0xdb,0x81,0xb3,0xa0,0xf4,0x45,0x7a,0x19,0xdf,0xee,0x78,0x34,0x60
};
public static final short[] S1 = {
0x55,0xc2,0x63,0x71,0x3b,0xc8,0x47,0x86,0x9f,0x3c,0xda,0x5b,0x29,0xaa,0xfd,0x77,
0x8c,0xc5,0x94,0x0c,0xa6,0x1a,0x13,0x00,0xe3,0xa8,0x16,0x72,0x40,0xf9,0xf8,0x42,
0x44,0x26,0x68,0x96,0x81,0xd9,0x45,0x3e,0x10,0x76,0xc6,0xa7,0x8b,0x39,0x43,0xe1,
0x3a,0xb5,0x56,0x2a,0xc0,0x6d,0xb3,0x05,0x22,0x66,0xbf,0xdc,0x0b,0xfa,0x62,0x48,
0xdd,0x20,0x11,0x06,0x36,0xc9,0xc1,0xcf,0xf6,0x27,0x52,0xbb,0x69,0xf5,0xd4,0x87,
0x7f,0x84,0x4c,0xd2,0x9c,0x57,0xa4,0xbc,0x4f,0x9a,0xdf,0xfe,0xd6,0x8d,0x7a,0xeb,
0x2b,0x53,0xd8,0x5c,0xa1,0x14,0x17,0xfb,0x23,0xd5,0x7d,0x30,0x67,0x73,0x08,0x09,
0xee,0xb7,0x70,0x3f,0x61,0xb2,0x19,0x8e,0x4e,0xe5,0x4b,0x93,0x8f,0x5d,0xdb,0xa9,
0xad,0xf1,0xae,0x2e,0xcb,0x0d,0xfc,0xf4,0x2d,0x46,0x6e,0x1d,0x97,0xe8,0xd1,0xe9,
0x4d,0x37,0xa5,0x75,0x5e,0x83,0x9e,0xab,0x82,0x9d,0xb9,0x1c,0xe0,0xcd,0x49,0x89,
0x01,0xb6,0xbd,0x58,0x24,0xa2,0x5f,0x38,0x78,0x99,0x15,0x90,0x50,0xb8,0x95,0xe4,
0xd0,0x91,0xc7,0xce,0xed,0x0f,0xb4,0x6f,0xa0,0xcc,0xf0,0x02,0x4a,0x79,0xc3,0xde,
0xa3,0xef,0xea,0x51,0xe6,0x6b,0x18,0xec,0x1b,0x2c,0x80,0xf7,0x74,0xe7,0xff,0x21,
0x5a,0x6a,0x54,0x1e,0x41,0x31,0x92,0x35,0xc4,0x33,0x07,0x0a,0xba,0x7e,0x0e,0x34,
0x88,0xb1,0x98,0x7c,0xf3,0x3d,0x60,0x6c,0x7b,0xca,0xd3,0x1f,0x32,0x65,0x04,0x28,
0x64,0xbe,0x85,0x9b,0x2f,0x59,0x8a,0xd7,0xb0,0x25,0xac,0xaf,0x12,0x03,0xe2,0xf2
};
// /**
// * 常量数组 D16bit short二维数组适配
// */
// public static final short[][] ZUC256_D = {
// {0x22,0x2F,0x24,0x2A,0x6D,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30},
// {0x22,0x2F,0x25,0x2A,0x6D,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30},
// {0x23,0x2F,0x24,0x2A,0x6D,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30},
// {0x23,0x2F,0x25,0x2A,0x6D,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30}
// };
public static final short D_COLS = 16;
/**
* 常量数组 D16bit short二维数组适配
*/
public static final short[] ZUC256_D_FLAT = {
// row 0
0x22,0x2F,0x24,0x2A,0x6D,0x40,0x40,0x40,
0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30,
// row 1
0x22,0x2F,0x25,0x2A,0x6D,0x40,0x40,0x40,
0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30,
// row 2
0x23,0x2F,0x24,0x2A,0x6D,0x40,0x40,0x40,
0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30,
// row 3
0x23,0x2F,0x25,0x2A,0x6D,0x40,0x40,0x40,
0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30
};
/** 读取 D[row][col],返回无符号值 0..255 */
public static short getD(short row, short col) {
// idx = row * 16 + col
short idx = (short)(row * D_COLS + col);
return (short)(ZUC256_D_FLAT[idx] & 0xFF);
}
/** 取一行 (返回一段16个short) */
public static void getDRow(short row, short[] out, short outOff) {
short base = (short)(row * D_COLS);
for (short i = 0; i < D_COLS; i++) {
out[(short)(outOff + i)] = ZUC256_D_FLAT[(short)(base + i)];
}
}
}

37
algo.py
View File

@@ -1,37 +0,0 @@
import os
from SCons.Script import *
# 工具链配置(Ubuntu gcc环境)
CROSS_TOOL = 'gcc'
PREFIX = '' # 本地编译不需要交叉编译前缀
# 目标配置
TARGET_NAME = 'app' # 更改为通用应用名称
BUILD_DIR = 'build' # 统一构建输出目录
# 工具链路径(使用系统默认的gcc工具链)
CC = PREFIX + 'gcc'
CXX = PREFIX + 'g++'
AS = PREFIX + 'gcc'
AR = PREFIX + 'ar'
LINK = PREFIX + 'gcc'
SIZE = PREFIX + 'size'
OBJDUMP = PREFIX + 'objdump'
OBJCPY = PREFIX + 'objcopy'
# 编译、链接选项(适用于Ubuntu gcc环境)
DEVICE = '-std=c99 -g -O2 -fvisibility=hidden -fno-common'
CFLAGS = DEVICE + ' -Wall -Wextra' # 添加更多警告选项
AFLAGS = '-c ' + DEVICE + ' -x assembler-with-cpp'
LFLAGS = DEVICE + ' -Wl,--gc-sections,-cref,-Map=' + os.path.join(BUILD_DIR, TARGET_NAME + '.map')
# 构建后处理命令(输出到 build 目录)
ASM_FILE = os.path.join(BUILD_DIR, TARGET_NAME + '.asm')
BIN_FILE = os.path.join(BUILD_DIR, TARGET_NAME + '.bin')
DUMP_ACTION = f'{OBJDUMP} -D -S $SOURCE > {ASM_FILE}'
POST_ACTION = f'{OBJCPY} -O binary $SOURCE {BIN_FILE}\n'
POST_ACTION += f'{SIZE} $SOURCE\n'
POST_ACTION += DUMP_ACTION

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,56 @@
@ECHO OFF
@REM SET PATH=""
@rem %JAVA_HOME%\bin\java -classpath %_CLASSES% com.sun.javacard.converter.Converter %*
SET _BUILD_DIR=%CD%
SET _PROJ_PATH="%_BUILD_DIR%\.."
SET _DELIVERY_PATH=%_BUILD_DIR%\Delivery
SET _SRC_PATH=%_PROJ_PATH%\Project\Src
SET _CAP_PATH=%_PROJ_PATH%\Project\bin\com\cscn\javacard
SET _OUT_PATH=%_PROJ_PATH%\Project\bin
SET _TOOLS_PATH=%_PROJ_PATH%\Tools
CD ..\Project
DEL /Q %_DELIVERY_PATH%\*.*
DEL /Q %_CAP_PATH%\*.*
RMDIR /S /Q %_OUT_PATH%
MKDIR %_OUT_PATH%
REM PAUSE
SET JAVA_HOME=%_TOOLS_PATH%\jdk1.5.0_19
SET JC_HOME=%_TOOLS_PATH%\jcdk222
SET PATH=%JAVA_HOME%\bin;%JC_HOME%\bin;%PATH%
SET EXT_API_PATH=%_TOOLS_PATH%\ext_api
SET _JavaC_HOME=%_TOOLS_PATH%\jdk1.5.0_19\jre\bin
SET _CLASS_PATH=%_TOOLS_PATH%\jcdk222\lib\api.jar;%EXT_API_PATH%\gp221.jar
SET JCDK_EXPORT_DIR=%_TOOLS_PATH%\api_exp\JCDK222
SET PROJ_EXPORT_DIR=%_OUT_PATH%
SET EXT_EXPORT_DIR=%_TOOLS_PATH%\api_exp\gp221
SET EXPORT_DIR=%JCDK_EXPORT_DIR%;%PROJ_EXPORT_DIR%;%EXT_EXPORT_DIR%
REM COMPILE JAVA TO CLASS
ECHO **********************************************
ECHO *** Compile Java Source Code ***
ECHO **********************************************
ECHO Setting Build Path
REM use <-verbose> display compile info
REM SET COMPILE_PARAM=-nowarn -verbose
SET COMPILE_PARAM= -nowarn
ECHO Compiling Java Card API source code
Call javac %COMPILE_PARAM% -classpath %_CLASS_PATH% %_SRC_PATH%\*.java -d %_OUT_PATH% -g
ECHO **********************************************
ECHO *** Convert Java Card Assembly File ***
ECHO **********************************************
CALL converter -verbose -nowarn -i -classdir .\bin -exportpath %EXPORT_DIR% -out EXP CAP -applet 0xA0:0x00:0x00:0x03:0x00:0x73:0x74:0x61:0x72:0x2E:0x61:0x70:0x70 com.cscn.XwSecurity com.cscn 0xA0:0x00:0x00:0x03:0x00:0x73:0x74:0x61:0x72:0x2E:0x70:0x6B:0x67 1.0
ECHO **********************************************
ECHO *** Copy Exp and Cap File ***
ECHO **********************************************
COPY %_CAP_PATH%\*.* %_BUILD_DIR%\Delivery\
PAUSE

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,99 @@
package com.cscn;
import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import org.globalplatform.GPSystem;
import org.globalplatform.SecureChannel;
/**
* @author liuww
*
*/
public class XwSecurity extends Applet {
//todo test
public static final byte INS_PROCESS_DATA_TEST = (byte)0xE3;
public static final byte INS_LOCATION_ENCRYPT = (byte)0xCA;
public static final byte INS_STORE_KEY = (byte)0xE2;
// public static final byte INS_INITIAL_UPDATE = (byte)0x50;
//
// public static final byte INS_EXTERNAL_AUTH = (byte)0x82;
private Method method;
byte[] key_store_byte;
public XwSecurity(byte[] bArray, short bOffset, byte bLength) {
// TODO Auto-generated constructor stub
method = new Method(); //todo new?
// key store -> flash
key_store_byte = new byte[120];
register(bArray, (short)(bOffset + 1), bArray[bOffset]);
}
public static void install(byte[] bArray, short bOffset, byte bLength)
{
//todo new?
// GP-compliant JavaCard applet registration
new XwSecurity(bArray, bOffset, bLength);
}
public void process(APDU apdu)
{
// Good practice: Return 9000 on SELECT
if(selectingApplet())
{
return;
}
if(method == null) {
return;
}
byte[] buf = apdu.getBuffer();
short off = ISO7816.OFFSET_CDATA;
short len = apdu.setIncomingAndReceive();
switch (buf[ISO7816.OFFSET_INS])
{
// case INS_INITIAL_UPDATE:
// SecureChannel sc = GPSystem.getSecureChannel();
// sc.processSecurity(apdu);
// break;
//
// case INS_EXTERNAL_AUTH:
// sc = GPSystem.getSecureChannel();
// sc.processSecurity(apdu);
// break;
//todo test
case INS_PROCESS_DATA_TEST:
method.testZuc256(apdu);
break;
case INS_LOCATION_ENCRYPT:
len = method.locationEncryptZuc(buf, off, len, key_store_byte);
apdu.setOutgoingAndSend(off, len);
break;
case INS_STORE_KEY:
len = method.updateKey(buf, off, len, key_store_byte);
apdu.setOutgoingAndSend(off, len);
break;
default:
// good practice: If you don't know the INStruction, say so:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
}

View File

@@ -0,0 +1,595 @@
//package com.cscn;
//
//
//import javacard.framework.JCSystem;
//
//import static com.cscn.Zuc256Util.L1;
//import static com.cscn.Zuc256Util.L2;
//import static com.cscn.Zuc256Util.add31;
//import static com.cscn.Zuc256Util.add32;
//import static com.cscn.Zuc256Util.add64;
//import static com.cscn.Zuc256Util.and64_7FFFFFFF_to32;
//import static com.cscn.Zuc256Util.create_64b_from_32b;
//import static com.cscn.Zuc256Util.makeU31;
//import static com.cscn.Zuc256Util.makeU32;
//import static com.cscn.Zuc256Util.rot31;
//import static com.cscn.Zuc256Util.shr32u1;
//import static com.cscn.Zuc256Util.shr64u_31;
//import static com.cscn.Zuc256Util.xor32;
//
///**
// * ZUC-256 核心:状态初始化、密钥字生成、密钥流生成。
// */
//public class Zuc256Core {
//
// private Zuc256Core() {}
//
// /** 初始化状态Key + IV */
// public static void initState(Zuc256State state, byte[] key32, byte[] iv) {
// zuc256SetMacKey(state, key32, iv, (short)0);
// }
//
// /** 生成单个密钥字 */
// public static void zuc256GenerateKeyword(Zuc256State state, short[] out) {
//// int[] LFSR = state.LFSR;
//// int R1 = state.R1;
//// int R2 = state.R2;
//// int X0, X1, X2, X3;
//// int W1, W2, U, V;
//// int Z;
//
// short[] LFSR_hi = state.LFSR_hi;
// short[] LFSR_lo = state.LFSR_lo;
//
// // 工作寄存器32位值的临时 out32 缓冲全用short[2][lo, hi]
// short[] X0 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] X1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] X2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] X3 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
//
// short[] R1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] R2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] W1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] W2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] U = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] V = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] Z = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] TMP0 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] TMP1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] TMP2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
//
// // 载入 R1,R2
// R1[0] = state.R1_lo;
// R1[1] = state.R1_hi;
// R2[0] = state.R2_lo;
// R2[1] = state.R2_hi;
//
//
// // BitReconstruction4
// short c15 = (short)((LFSR_lo[15] & (short)0x8000) >>> 15); // 左移产生的进位
// X0[1] = (short)(((LFSR_hi[15] & (short)0x7FFF) << 1) | (short)(c15 & 0x0001)); // hi
// X0[0] = LFSR_lo[14]; // lo
//
// // X1 = ((L11 & 0xFFFF) << 16) | (L9 >>> 15)
// X1[1] = LFSR_lo[11];
// X1[0] = (short)((((LFSR_lo[9] & (short)0x8000) >>> 15) & 0X0001) | (LFSR_hi[9] << 1));
//
// // X2 = ((L7 & 0xFFFF) << 16) | (L5 >>> 15)
// X2[1] = LFSR_lo[7];
// X2[0] = (short)((((LFSR_lo[5] & (short)0x8000) >>> 15) & 0X0001) | (LFSR_hi[5] << 1));
//
// // X3 = ((L2 & 0xFFFF) << 16) | (L0 >>> 15)
// X3[1] = LFSR_lo[2];
// X3[0] = (short)((((LFSR_lo[0] & (short)0x8000) >>> 15) & 0X0001) | (LFSR_hi[0] << 1));
//
//
//
// // ---- 输入X0,X1,X2,X3,R1,R2 均为 short[2]; 输出Z,W1,W2,U,V ----
//
// // Z = X3 ^ ((X0 ^ R1) + R2)
// xor32(X0[0], X0[1], R1[0], R1[1], TMP0); // TMP0 = X0 ^ R1
// add32(TMP0[0], TMP0[1], R2[0], R2[1], TMP1); // TMP1 = TMP0 + R2
// xor32(X3[0], X3[1], TMP1[0], TMP1[1], Z); // Z = X3 ^ TMP1
//
// // F_(X1, X2)
// // W1 = R1 + X1
// add32(R1[0], R1[1], X1[0], X1[1], W1);
//
// // W2 = R2 ^ X2
// xor32(R2[0], R2[1], X2[0], X2[1], W2);
//
// // U = L1((W1 << 16) | (W2 >>> 16))
// // (W1<<16): lo=0, hi=W1_lo
// // (W2>>>16): lo=W2_hi, hi=0
// // OR 结果: lo=W2_hi, hi=W1_lo
// L1(W2[1], W1[0], U);
//
// // V = L2((W2 << 16) | (W1 >>> 16))
// // (W2<<16): lo=0, hi=W2_lo
// // (W1>>>16): lo=W1_hi, hi=0
// // OR 结果: lo=W1_hi, hi=W2_lo
// L2(W1[1], W2[0], V);
//
//
//// R1 = makeU32(Zuc256Tables.S0[(U >>> 24) & 0xFF],
//// Zuc256Tables.S1[(U >>> 16) & 0xFF],
//// Zuc256Tables.S0[(U >>> 8) & 0xFF],
//// Zuc256Tables.S1[U & 0xFF]);
// makeU32(
// (short)(Zuc256Tables.S0[((U[1] >>> 8) & 0xFF)] & 0xFF), // (U >>> 24) & 0xFF
// (short)(Zuc256Tables.S1[(U[1] & 0xFF)] & 0xFF), // (U >>> 16) & 0xFF
// (short)(Zuc256Tables.S0[((U[0] >>> 8) & 0xFF)] & 0xFF), // (U >>> 8) & 0xFF
// (short)(Zuc256Tables.S1[(U[0] & 0xFF)] & 0xFF), // (U >>> 0) & 0xFF
// R1);
//
//// R2 = makeU32(Zuc256Tables.S0[(V >>> 24) & 0xFF],
//// Zuc256Tables.S1[(V >>> 16) & 0xFF],
//// Zuc256Tables.S0[(V >>> 8) & 0xFF],
//// Zuc256Tables.S1[V & 0xFF]);
// makeU32(
// (short)(Zuc256Tables.S0[((V[1] >>> 8) & 0xFF)] & 0xFF), // (V >>> 24) & 0xFF
// (short)(Zuc256Tables.S1[(V[1] & 0xFF)] & 0xFF), // (V >>> 16) & 0xFF
// (short)(Zuc256Tables.S0[((V[0] >>> 8) & 0xFF)] & 0xFF), // (V >>> 8) & 0xFF
// (short)(Zuc256Tables.S1[(V[0] & 0xFF)] & 0xFF), // (V >>> 0) & 0xFF
// R2);
//
//
//
//// // LFSRWithWorkMode
//// long a = LFSR[0];
//// a += (long)LFSR[0] << 8;
//// a += (long)LFSR[4] << 20;
//// a += (long)LFSR[10] << 21;
//// a += (long)LFSR[13] << 17;
//// a += (long)LFSR[15] << 15;
// // ---- 先准备累加器 A (64位) ----
// short[] A = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // 64位累加器初始全0
// A[0] = 0; A[1] = 0; A[2] = 0; A[3] = 0;
//
// // 临时缓冲
// short[] tmp32 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);; // 保存一个32位数 (lo,hi)
// short[] tmp64 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);; // 保存移位后的64位数
//
// // a = LFSR[0]
// tmp32[0] = state.LFSR_lo[0];
// tmp32[1] = state.LFSR_hi[0];
// create_64b_from_32b(tmp64, tmp32, (short)0);
// add64(A, tmp64);
//
// // a += (LFSR[0] << 8)
// create_64b_from_32b(tmp64, tmp32, (short)8);
// add64(A, tmp64);
//
// // a += (LFSR[4] << 20)
// tmp32[0] = state.LFSR_lo[4];
// tmp32[1] = state.LFSR_hi[4];
// create_64b_from_32b(tmp64, tmp32, (short)20);
// add64(A, tmp64);
//
// // a += (LFSR[10] << 21)
// tmp32[0] = state.LFSR_lo[10];
// tmp32[1] = state.LFSR_hi[10];
// create_64b_from_32b(tmp64, tmp32, (short)21);
// add64(A, tmp64);
//
// // a += (LFSR[13] << 17)
// tmp32[0] = state.LFSR_lo[13];
// tmp32[1] = state.LFSR_hi[13];
// create_64b_from_32b(tmp64, tmp32, (short)17);
// add64(A, tmp64);
//
// // a += (LFSR[15] << 15)
// tmp32[0] = state.LFSR_lo[15];
// tmp32[1] = state.LFSR_hi[15];
// create_64b_from_32b(tmp64, tmp32, (short)15);
// add64(A, tmp64);
//
//// a = (a & 0x7FFFFFFF) + (a >>> 31);
// // ---- 第一次折叠a = (a & 0x7FFFFFFF) + (a >>> 31) ----
// short[] low31 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] r31 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
//
// and64_7FFFFFFF_to32(A, low31); // low31 = A & 0x7FFFFFFF
// shr64u_31(A, r31); // r31 = A >>> 31
//
// A[0]=0; A[1]=0; A[2]=0; A[3]=0;
// add64(A, low31);
// add64(A, r31);
//// int v = (int) ((a & 0x7FFFFFFF) + (a >>> 31));
// // ---- 第二次折叠,得到 v32位----
// short[] low31b = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] r31b = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] v64 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
//
// and64_7FFFFFFF_to32(A, low31b);
// shr64u_31(A, r31b);
//
// v64[0]=0; v64[1]=0; v64[2]=0; v64[3]=0;
// add64(v64, low31b);
// add64(v64, r31b);
//
// // v = 32位取 v64 的低两段
// short v_lo = v64[0];
// short v_hi = (short)(v64[1] & 0x7FFF); // 只保留31位
//
//// System.arraycopy(LFSR, 1, LFSR, 0, 15);
// // LFSR_lo 向左移
// for (short i = 0; i < (short)15; i++) {
// state.LFSR_lo[i] = state.LFSR_lo[(short)(i + 1)];
// }
// // LFSR_hi 向左移
// for (short i = 0; i < (short)15; i++) {
// state.LFSR_hi[i] = state.LFSR_hi[(short)(i + 1)];
// }
//
//// LFSR[15] = v;
// // ---- 写回 LFSR[15] ----
// state.LFSR_lo[15] = v_lo;
// state.LFSR_hi[15] = v_hi;
//
//// state.R1 = R1;
//// state.R2 = R2;
// state.R1_lo = R1[0];
// state.R1_hi = R1[1];
//
// state.R2_lo = R2[0];
// state.R2_hi = R2[1];
//
//
//// return Z;
// out[0] = Z[0];
// out[1] = Z[1];
//
// }
//
// // 生成指定长度的密钥流
// public static void zuc256GenerateKeystream(Zuc256State state,
// short nwords,
// short[] keystream_hi,
// short[] keystream_lo) {
// // 临时存放一个 32 位关键字
// short[] tmp = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// for (short i = 0; i < nwords; i++) {
// // 生成一个关键字 -> tmp[0]=lo, tmp[1]=hi
// zuc256GenerateKeyword(state, tmp);
// // 存入输出数组
// keystream_lo[i] = tmp[0];
// keystream_hi[i] = tmp[1];
// }
// }
//
//
//
//
// // 初始化MAC密钥
// private static void zuc256SetMacKey(Zuc256State state, byte[] K, byte[] IV, short macbits) {
// short[] D = JCSystem.makeTransientShortArray(Zuc256Tables.D_COLS, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] TMP = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] X0 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] X1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] X2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] R1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] R2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] W = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] W1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] W2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] U = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] V = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] T = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] T2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
//
//
//// int IV17 = (IV[17] & 0xFF) >> 2;
//// int IV18 = ((IV[17] & 0x03) << 4) | ((IV[18] & 0xFF) >> 4);
//// int IV19 = ((IV[18] & 0x0F) << 2) | ((IV[19] & 0xFF) >> 6);
//// int IV20 = IV[19] & 0x3F;
//// int IV21 = (IV[20] & 0xFF) >> 2;
//// int IV22 = ((IV[20] & 0x03) << 4) | ((IV[21] & 0xFF) >> 4);
//// int IV23 = ((IV[21] & 0x0F) << 2) | ((IV[22] & 0xFF) >> 6);
//// int IV24 = IV[22] & 0x3F;
// // IV 拆分
// short IV17 = (short)((IV[17] & 0xFF) >>> 2);
// short IV18 = (short)(((IV[17] & 0x03) << 4) | ((IV[18] & 0xFF) >>> 4));
// short IV19 = (short)(((IV[18] & 0x0F) << 2) | ((IV[19] & 0xFF) >>> 6));
// short IV20 = (short)(IV[19] & 0x3F);
// short IV21 = (short)((IV[20] & 0xFF) >>> 2);
// short IV22 = (short)(((IV[20] & 0x03) << 4) | ((IV[21] & 0xFF) >>> 4));
// short IV23 = (short)(((IV[21] & 0x0F) << 2) | ((IV[22] & 0xFF) >>> 6));
// short IV24 = (short)(IV[22] & 0x3F);
//
//// D = (macbits / 32 < 3) ? Zuc256Tables.ZUC256_D[macbits / 32] : Zuc256Tables.ZUC256_D[3];
// short row = (short)((macbits / 32) < 3 ? (macbits / 32) : 3);
// Zuc256Tables.getDRow(row, D, (short)0);
// Zuc256Tables.getDRow(row, D, (short)0);
//
//
// short[] tmp = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // 临时存储 makeU31 输出 (lo,hi)
//
// // 逐项装载 LFSR
//// LFSR[0] = makeU31(K[0] & 0xFF, D[0], K[21] & 0xFF, K[16] & 0xFF);
// makeU31((short)(K[0] & 0xFF), (short)D[0], (short)(K[21] & 0xFF), (short)(K[16] & 0xFF), tmp);
// state.LFSR_lo[0] = tmp[0]; state.LFSR_hi[0] = tmp[1];
//
//// LFSR[1] = makeU31(K[1] & 0xFF, D[1], K[22] & 0xFF, K[17] & 0xFF);
// makeU31((short)(K[1] & 0xFF), (short)D[1], (short)(K[22] & 0xFF), (short)(K[17] & 0xFF), tmp);
// state.LFSR_lo[1] = tmp[0]; state.LFSR_hi[1] = tmp[1];
//
//// LFSR[2] = makeU31(K[2] & 0xFF, D[2], K[23] & 0xFF, K[18] & 0xFF);
// makeU31((short)(K[2] & 0xFF), (short)D[2], (short)(K[23] & 0xFF), (short)(K[18] & 0xFF), tmp);
// state.LFSR_lo[2] = tmp[0]; state.LFSR_hi[2] = tmp[1];
//
//// LFSR[3] = makeU31(K[3] & 0xFF, D[3], K[24] & 0xFF, K[19] & 0xFF);
// makeU31((short)(K[3] & 0xFF), (short)D[3], (short)(K[24] & 0xFF), (short)(K[19] & 0xFF), tmp);
// state.LFSR_lo[3] = tmp[0]; state.LFSR_hi[3] = tmp[1];
//
//// LFSR[4] = makeU31(K[4] & 0xFF, D[4], K[25] & 0xFF, K[20] & 0xFF);
// makeU31((short)(K[4] & 0xFF), (short)D[4], (short)(K[25] & 0xFF), (short)(K[20] & 0xFF), tmp);
// state.LFSR_lo[4] = tmp[0]; state.LFSR_hi[4] = tmp[1];
//
//// LFSR[5] = makeU31(IV[0] & 0xFF, (D[5] | IV17), K[5] & 0xFF, K[26] & 0xFF);
// makeU31((short)(IV[0] & 0xFF), (short)(D[5] | IV17), (short)(K[5] & 0xFF), (short)(K[26] & 0xFF), tmp);
// state.LFSR_lo[5] = tmp[0]; state.LFSR_hi[5] = tmp[1];
//
//// LFSR[6] = makeU31(IV[1] & 0xFF, (D[6] | IV18), K[6] & 0xFF, K[27] & 0xFF);
// makeU31((short)(IV[1] & 0xFF), (short)(D[6] | IV18), (short)(K[6] & 0xFF), (short)(K[27] & 0xFF), tmp);
// state.LFSR_lo[6] = tmp[0]; state.LFSR_hi[6] = tmp[1];
//
//// LFSR[7] = makeU31(IV[10] & 0xFF, (D[7] | IV19), K[7] & 0xFF, IV[2] & 0xFF);
// makeU31((short)(IV[10] & 0xFF), (short)(D[7] | IV19), (short)(K[7] & 0xFF), (short)(IV[2] & 0xFF), tmp);
// state.LFSR_lo[7] = tmp[0]; state.LFSR_hi[7] = tmp[1];
//
//// LFSR[8] = makeU31(K[8] & 0xFF, (D[8] | IV20), IV[3] & 0xFF, IV[11] & 0xFF);
// makeU31((short)(K[8] & 0xFF), (short)(D[8] | IV20), (short)(IV[3] & 0xFF), (short)(IV[11] & 0xFF), tmp);
// state.LFSR_lo[8] = tmp[0]; state.LFSR_hi[8] = tmp[1];
//
//// LFSR[9] = makeU31(K[9] & 0xFF, (D[9] | IV21), IV[12] & 0xFF, IV[4] & 0xFF);
// makeU31((short)(K[9] & 0xFF), (short)(D[9] | IV21), (short)(IV[12] & 0xFF), (short)(IV[4] & 0xFF), tmp);
// state.LFSR_lo[9] = tmp[0]; state.LFSR_hi[9] = tmp[1];
//
//// LFSR[10] = makeU31(IV[5] & 0xFF, (D[10] | IV22), K[10] & 0xFF, K[28] & 0xFF);
// makeU31((short)(IV[5] & 0xFF), (short)(D[10] | IV22), (short)(K[10] & 0xFF), (short)(K[28] & 0xFF), tmp);
// state.LFSR_lo[10] = tmp[0]; state.LFSR_hi[10] = tmp[1];
//
//// LFSR[11] = makeU31(K[11] & 0xFF, (D[11] | IV23), IV[6] & 0xFF, IV[13] & 0xFF);
// makeU31((short)(K[11] & 0xFF), (short)(D[11] | IV23), (short)(IV[6] & 0xFF), (short)(IV[13] & 0xFF), tmp);
// state.LFSR_lo[11] = tmp[0]; state.LFSR_hi[11] = tmp[1];
//
//// LFSR[12] = makeU31(K[12] & 0xFF, (D[12] | IV24), IV[7] & 0xFF, IV[14] & 0xFF);
// makeU31((short)(K[12] & 0xFF), (short)(D[12] | IV24), (short)(IV[7] & 0xFF), (short)(IV[14] & 0xFF), tmp);
// state.LFSR_lo[12] = tmp[0]; state.LFSR_hi[12] = tmp[1];
//
//// LFSR[13] = makeU31(K[13] & 0xFF, D[13], IV[15] & 0xFF, IV[8] & 0xFF);
// makeU31((short)(K[13] & 0xFF), (short)D[13], (short)(IV[15] & 0xFF), (short)(IV[8] & 0xFF), tmp);
// state.LFSR_lo[13] = tmp[0]; state.LFSR_hi[13] = tmp[1];
//
//// LFSR[14] = makeU31(K[14] & 0xFF, (D[14] | (K[31] >>> 4)), IV[16] & 0xFF, IV[9] & 0xFF);
// makeU31((short)(K[14] & 0xFF), (short)(D[14] | ((K[31] & 0xFF) >>> 4)), (short)(IV[16] & 0xFF), (short)(IV[9] & 0xFF), tmp);
// state.LFSR_lo[14] = tmp[0]; state.LFSR_hi[14] = tmp[1];
//
//// LFSR[15] = makeU31(K[15] & 0xFF, (D[15] | (K[31] & 0x0F)), K[30] & 0xFF, K[29] & 0xFF);
// makeU31((short)(K[15] & 0xFF), (short)(D[15] | (K[31] & 0x0F)), (short)(K[30] & 0xFF), (short)(K[29] & 0xFF), tmp);
// state.LFSR_lo[15] = tmp[0]; state.LFSR_hi[15] = tmp[1];
//
//
// short c15_2 = 0;
// for (short i = 0; i < 32; i++) {
// // BitReconstruction3
//// X0 = ((LFSR[15] & 0x7FFF8000) << 1) | (LFSR[14] & 0xFFFF);
// // X0 = ((L15 & 0x7FFF8000)<<1) | (L14 & 0xFFFF)
// c15_2 = (short)((state.LFSR_lo[15] & (short)0x8000) >>> 15);
// X0[1] = (short)(((state.LFSR_hi[15] & (short)0x7FFF) << 1) | (short)(c15_2 & 0x0001));
// X0[0] = state.LFSR_lo[14];
//
//// X1 = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >>> 15);
// // X1 = ((L11 & 0xFFFF)<<16) | (L9>>>15)
// X1[1] = state.LFSR_lo[11];
// X1[0] = (short)((((state.LFSR_lo[9] & (short)0x8000) >>> 15) & 0X0001) | (state.LFSR_hi[9] << 1));
//
//// X2 = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >>> 15);
// // X2 = ((L7 & 0xFFFF)<<16) | (L5>>>15)
// X2[1] = state.LFSR_lo[7];
// X2[0] = (short)((((state.LFSR_lo[5] & (short)0x8000) >>> 15) & 0X0001) | (state.LFSR_hi[5] << 1));
//
//
//
// // F(X0, X1, X2)
// // W = (X0 ^ R1) + R2
// xor32(X0[0], X0[1], R1[0], R1[1], TMP);
// add32(TMP[0], TMP[1], R2[0], R2[1], W);
//
// // W1 = R1 + X1
// add32(R1[0], R1[1], X1[0], X1[1], W1);
//
// // W2 = R2 ^ X2
// xor32(R2[0], R2[1], X2[0], X2[1], W2);
//
// // U = L1((W1<<16) | (W2>>>16))
// L1(W2[1], W1[0], U);
//
// // V = L2((W2<<16) | (W1>>>16))
// L2(W1[1], W2[0], V);
//
//// R1 = makeU32(Zuc256Tables.S0[(U >>> 24) & 0xFF],
//// Zuc256Tables.S1[(U >>> 16) & 0xFF],
//// Zuc256Tables.S0[(U >>> 8) & 0xFF],
//// Zuc256Tables.S1[U & 0xFF]);
////
//// R2 = makeU32(Zuc256Tables.S0[(V >>> 24) & 0xFF],
//// Zuc256Tables.S1[(V >>> 16) & 0xFF],
//// Zuc256Tables.S0[(V >>> 8) & 0xFF],
//// Zuc256Tables.S1[V & 0xFF]);
// // 更新 R1,R2
// makeU32(
// (short)(Zuc256Tables.S0[((U[1] >>> 8) & 0xFF)] & 0xFF),
// (short)(Zuc256Tables.S1[(U[1] & 0xFF)] & 0xFF),
// (short)(Zuc256Tables.S0[((U[0] >>> 8) & 0xFF)] & 0xFF),
// (short)(Zuc256Tables.S1[(U[0] & 0xFF)] & 0xFF),
// R1);
//
// makeU32(
// (short)(Zuc256Tables.S0[((V[1] >>> 8) & 0xFF)] & 0xFF),
// (short)(Zuc256Tables.S1[(V[1] & 0xFF)] & 0xFF),
// (short)(Zuc256Tables.S0[((V[0] >>> 8) & 0xFF)] & 0xFF),
// (short)(Zuc256Tables.S1[(V[0] & 0xFF)] & 0xFF),
// R2);
//
// // LFSRWithInitialisationMode(W >> 1)
//// int v = LFSR[0];
// V[0] = state.LFSR_lo[0];
// V[1] = state.LFSR_hi[0];
//
// // v = add31(v, rot31(state.LFSR[0], 8))
// rot31(state.LFSR_lo[0], state.LFSR_hi[0], (short)8, T);
// add31(V[0], V[1], T[0], T[1], V);
//
//// v = add31(v, rot31(state.LFSR[4], 20));
// rot31(state.LFSR_lo[4], state.LFSR_hi[4], (short)20, T);
// add31(V[0], V[1], T[0], T[1], V);
//
//// v = add31(v, rot31(state.LFSR[10], 21));
// rot31(state.LFSR_lo[10], state.LFSR_hi[10], (short)21, T);
// add31(V[0], V[1], T[0], T[1], V);
//
//// v = add31(v, rot31(state.LFSR[13], 17));
// rot31(state.LFSR_lo[13], state.LFSR_hi[13], (short)17, T);
// add31(V[0], V[1], T[0], T[1], V);
//
//// v = add31(v, rot31(state.LFSR[15], 15));
// rot31(state.LFSR_lo[15], state.LFSR_hi[15], (short)15, T);
// add31(V[0], V[1], T[0], T[1], V);
//
//// v = add31(v, W >>> 1);
// shr32u1(W[0], W[1], T2); // T2[0]=lo, T2[1]=hi无符号>>>1
// T2[1] = (short)(T2[1] & (short)0xFFFF); // 只保留31位
// add31(V[0], V[1], T2[0], T2[1], V);
//
// // System.arraycopy(state.LFSR, 1, state.LFSR, 0, 15)
//// 相当于 System.arraycopy(state.LFSR_lo, 1, state.LFSR_lo, 0, 15);
// for (short j = 0; j < (short)15; j++) {
// state.LFSR_lo[j] = state.LFSR_lo[(short)(j + 1)];
// }
//// 相当于 System.arraycopy(state.LFSR_hi, 1, state.LFSR_hi, 0, 15);
// for (short j = 0; j < (short)15; j++) {
// state.LFSR_hi[j] = state.LFSR_hi[(short)(j + 1)];
// }
//
//// state.LFSR[15] = v;
// state.LFSR_lo[15] = V[0];
// state.LFSR_hi[15] = (short)(V[1] & 0x7FFF);
// }
//
// // BitReconstruction2
//// X1 = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >>> 15);
// X1[1] = state.LFSR_lo[11];
// X1[0] = (short)((((state.LFSR_lo[9] & (short)0x8000) >>> 15) & 0X0001) | (state.LFSR_hi[9] << 1));
//
//// X2 = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >>> 15);
// X2[1] = state.LFSR_lo[7];
// X2[0] = (short)((((state.LFSR_lo[5] & (short)0x8000) >>> 15) & 0X0001) | (state.LFSR_hi[5] << 1));
//
// // F_(X1, X2)
//// W1 = R1 + X1;
// add32(R1[0], R1[1], X1[0], X1[1], W1); // W1 = R1 + X1
//// W2 = R2 ^ X2;
// xor32(R2[0], R2[1], X2[0], X2[1], W2); // W2 = R2 ^ X2
//
//// U = L1((W1 << 16) | (W2 >>> 16));
// // U = L1((W1<<16)|(W2>>>16)) → lo=W2_hi, hi=W1_lo
// L1(W2[1], W1[0], U);
//
//// V = L2((W2 << 16) | (W1 >>> 16));
// // V = L2((W2<<16)|(W1>>>16)) → lo=W1_hi, hi=W2_lo
// L2(W1[1], W2[0], V);
//
//// R1 = makeU32(Zuc256Tables.S0[(U >>> 24) & 0xFF],
//// Zuc256Tables.S1[(U >>> 16) & 0xFF],
//// Zuc256Tables.S0[(U >>> 8) & 0xFF],
//// Zuc256Tables.S1[U & 0xFF]);
// makeU32(
// (short)(Zuc256Tables.S0[((U[1] >>> 8) & 0xFF)] & 0xFF),
// (short)(Zuc256Tables.S1[(U[1] & 0xFF)] & 0xFF),
// (short)(Zuc256Tables.S0[((U[0] >>> 8) & 0xFF)] & 0xFF),
// (short)(Zuc256Tables.S1[(U[0] & 0xFF)] & 0xFF),
// R1);
//
//// R2 = makeU32(Zuc256Tables.S0[(V >>> 24) & 0xFF],
//// Zuc256Tables.S1[(V >>> 16) & 0xFF],
//// Zuc256Tables.S0[(V >>> 8) & 0xFF],
//// Zuc256Tables.S1[V & 0xFF]);
// makeU32(
// (short)(Zuc256Tables.S0[((V[1] >>> 8) & 0xFF)] & 0xFF),
// (short)(Zuc256Tables.S1[(V[1] & 0xFF)] & 0xFF),
// (short)(Zuc256Tables.S0[((V[0] >>> 8) & 0xFF)] & 0xFF),
// (short)(Zuc256Tables.S1[(V[0] & 0xFF)] & 0xFF),
// R2);
//
// // ---- LFSRWithWorkMode ----
// short[] A = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);; // 64位累加器
// short[] tmp32 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);;
// short[] tmp64 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);;
//
// // LFSRWithWorkMode
//// long a = LFSR[0];
// tmp32[0] = state.LFSR_lo[0];
// tmp32[1] = state.LFSR_hi[0];
// create_64b_from_32b(tmp64, tmp32, (short)0); add64(A, tmp64);
//
//// a += (long)LFSR[0] << 8;
// create_64b_from_32b(tmp64, tmp32, (short)8); add64(A, tmp64);
//
//// a += (long)LFSR[4] << 20;
// tmp32[0] = state.LFSR_lo[4]; tmp32[1] = state.LFSR_hi[4];
// create_64b_from_32b(tmp64, tmp32, (short)20); add64(A, tmp64);
//
//// a += (long)LFSR[10] << 21;
// tmp32[0] = state.LFSR_lo[10]; tmp32[1] = state.LFSR_hi[10];
// create_64b_from_32b(tmp64, tmp32, (short)21); add64(A, tmp64);
//
//// a += (long)LFSR[13] << 17;
// tmp32[0] = state.LFSR_lo[13]; tmp32[1] = state.LFSR_hi[13];
// create_64b_from_32b(tmp64, tmp32, (short)17); add64(A, tmp64);
//
//// a += (long)LFSR[15] << 15;
// tmp32[0] = state.LFSR_lo[15]; tmp32[1] = state.LFSR_hi[15];
// create_64b_from_32b(tmp64, tmp32, (short)15); add64(A, tmp64);
//
//// a = (a & 0x7FFFFFFF) + (a >>> 31);
// short[] low31 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);;
// short[] r31 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);;
// and64_7FFFFFFF_to32(A, low31);
// shr64u_31(A, r31);
//
// short[] v64 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);;
// add64(v64, low31);
// add64(v64, r31);
//
//// int v = (int) ((a & 0x7FFFFFFF) + (a >>> 31));
// and64_7FFFFFFF_to32(v64, low31);
// shr64u_31(v64, r31);
// short[] vv = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);;
// add64(vv, low31);
// add64(vv, r31);
//
// short v_lo = vv[0];
// short v_hi = (short)(vv[1] & 0x7FFF);
//
//// LFSR左移
//// System.arraycopy(LFSR, 1, LFSR, 0, 15);
// // LFSR_lo 向左移
// for (short i = 0; i < (short)15; i++) {
// state.LFSR_lo[i] = state.LFSR_lo[(short)(i + 1)];
// }
// // LFSR_hi 向左移
// for (short i = 0; i < (short)15; i++) {
// state.LFSR_hi[i] = state.LFSR_hi[(short)(i + 1)];
// }
//
//// LFSR[15] = v;
// state.LFSR_lo[15] = v_lo;
// state.LFSR_hi[15] = v_hi;
//
// state.R1_lo = R1[0]; state.R1_hi = R1[1];
// state.R2_lo = R2[0]; state.R2_hi = R2[1];
// }
//}
//

View File

@@ -0,0 +1,66 @@
//package com.cscn;
//
///**
// * 演示主函数
// */
//public final class Zuc256Demo {
//
// public static void main(String[] args) {
// // 1. 明文
// byte[] plaintext = "ZUC256对称加解密测试:1234567890".getBytes();
// int plaintextLen = plaintext.length;
// System.out.println("明文: " + new String(plaintext));
// printHex("明文(十六进制)", plaintext, plaintextLen);
//
// // 2. 密钥(32字节ASCII)
// byte[] key = "0123456789abcdef0123456789abcdef".getBytes();
// printHex("密钥", key, 32);
//
// // 3. 初始向量(25字节ASCII)
// byte[] inputIv25Byte = "0123456789abcdefg01234567".getBytes();
// byte[] iv = new byte[23];
// extractIv(inputIv25Byte, iv);
// printHex("提取后的IV", iv, 23);
//
// // 4. 分配加密/解密缓冲区
// byte[] ciphertext = new byte[plaintextLen];
// byte[] decryptedtext = new byte[plaintextLen];
//
// // 5. 加密
// Zuc256State stateEnc = new Zuc256State();
// Zuc256Core.initState(stateEnc, key, iv);
// zuc256Crypt(stateEnc, plaintext, plaintextLen, ciphertext);
// printHex("密文", ciphertext, plaintextLen);
//
// // 6. 解密(重新初始化状态)
// Zuc256State stateDec = new Zuc256State();
// Zuc256Core.initState(stateDec, key, iv);
// zuc256Crypt(stateDec, ciphertext, plaintextLen, decryptedtext);
// printHex("解密后", decryptedtext, plaintextLen);
// System.out.println("解密文本: " + new String(decryptedtext));
//
// // 7. 验证结果
// if (Arrays.equals(plaintext, decryptedtext)) {
// System.out.println("=== 测试成功: 解密结果与明文一致 ===");
// } else {
// System.out.println("=== 测试失败: 解密结果与明文不一致 ===");
// }
// }
//
// // 一次性加密
// public static void zuc256Crypt(Zuc256State state, byte[] in, int inlen, byte[] out) {
// if (state == null || in == null || out == null) return;
//
// Zuc256EncryptCtx ctx = new Zuc256EncryptCtx(state);
//
// // 执行加解密
// ctx.update(in, inlen, out);
// int remainingOffset = (inlen / 4) * 4;
// byte[] finishOut = new byte[out.length - remainingOffset];
// if (finishOut.length > 0) {
// System.arraycopy(out, remainingOffset, finishOut, 0, finishOut.length);
// }
// ctx.finish(finishOut);
// System.arraycopy(finishOut, 0, out, remainingOffset, finishOut.length);
// }
//}

View File

@@ -0,0 +1,214 @@
//package com.cscn;
//
//import javacard.framework.JCSystem;
//import javacard.framework.Util;
//
//import static com.cscn.Zuc256Core.zuc256GenerateKeystream;
//import static com.cscn.Zuc256Core.zuc256GenerateKeyword;
//import static com.cscn.Zuc256Util.getU32;
//import static com.cscn.Zuc256Util.putU32;
//import static com.cscn.Zuc256Util.xor32;
//
//
///**
// * 加密上下文类
// */
//public final class Zuc256EncryptCtx {
// Zuc256State state;
// byte[] buf;
// short buflen;
//
// public Zuc256EncryptCtx(Zuc256State state, byte[] buf){
// this.state = state;
// this.buf = buf;
// }
//
// public Zuc256EncryptCtx(Zuc256State state){
// this.state = state;
// this.buf = JCSystem.makeTransientByteArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// }
//
// public Zuc256EncryptCtx(){
// this.state = new Zuc256State(); //todo how to put in ram?
// this.buf = JCSystem.makeTransientByteArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// }
//
// // 初始化加密上下文
// public void initZuc256EncryptCtx(byte[] key32, byte[] iv) {
//// Arrays.fill(this.buf, (byte) 0);
// for (short i = 0; i < (short)this.buf.length; i++) {
// this.buf[i] = (byte)0;
// }
// this.buflen = 0;
// Zuc256Core.initState(this.state, key32, iv);
// }
//
// // 分阶段处理加密数据
// public void updateZuc256EncryptCtx(byte[] in, short inlen, byte[] out) {
// if (in == null || out == null || inlen == 0) return;
//
// short inPos = 0; // 输入偏移
// short outPos = 0; // 输出偏移
//
// // 处理缓冲区中剩余的非4字节数据
// if (this.buflen > 0) {
//// int need = 4 - this.buflen;
// short need = (short)(4 - this.buflen);
//// int copy = Math.min(inlen, need);
// short copy = (short)((inlen < need) ? inlen : need);
//
// // 替代 System.arraycopy(in, 0, this.buf, this.buflen, copy);
// Util.arrayCopyNonAtomic(in, (short)0, this.buf, this.buflen, copy);
//
// this.buflen += copy;
//
// // 调整输入指针和长度
//// byte[] newIn = new byte[inlen - copy];
//// if (inlen - copy > 0) {
//// System.arraycopy(in, copy, newIn, 0, inlen - copy);
//// }
//// in = newIn;
//// inlen -= copy;
// // 推进输入指针与剩余长度
// inPos += copy;
// inlen -= copy;
//
// // 缓冲区已满处理一个完整的4字节块
// if (this.buflen == 4) {
//// int keystream = zuc256GenerateKeyword(this.state);
// short[] ks = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// zuc256GenerateKeyword(this.state, ks); // ks[0]=lo, ks[1]=hi
//
//// int plain = getU32(this.buf, 0);
// // 取出 4 字节明文 → plain[0]=lo, plain[1]=hi
// short[] plain = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// getU32(this.buf, (short)0, plain);
//
//// putU32(out, 0, plain ^ keystream);
// // plain ^ ks → res
// short[] res = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// xor32(plain[0], plain[1], ks[0], ks[1], res);
// // 写回 out 的前4字节
// putU32(out, (short)0, res[0], res[1]);
//
// this.buflen = 0;
//// Arrays.fill(this.buf, (byte) 0);
// for (short i = 0; i < (short)this.buf.length; i++) {
// this.buf[i] = (byte)0;
// }
//
// // 调整输出指针
//// byte[] newOut = new byte[out.length - 4];
//// if (out.length - 4 > 0) {
//// System.arraycopy(out, 4, newOut, 0, out.length - 4);
//// }
//// out = newOut;
// // 这里C实现就是直接指针+4的。JavaSE实现搞这个new干嘛。。
// outPos += 4;
// }
// }
//
// // 处理完整的4字节块
//// int fullBlocks = inlen / 4;
// short fullBlocks = (short) (inlen / 4);
// if (fullBlocks > 0) {
//// int[] keystream = new int[fullBlocks];
// short[] ks_hi = JCSystem.makeTransientShortArray(fullBlocks, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] ks_lo = JCSystem.makeTransientShortArray(fullBlocks, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
//
//// zuc256GenerateKeystream(this.state, fullBlocks, keystream);
// zuc256GenerateKeystream(this.state, fullBlocks, ks_hi, ks_lo);
//
// // 临时装一个32位字
// short[] word = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
//
// // 逐块异或加密
// for (short i = 0; i < fullBlocks; i++) {
//// int plain = getU32(in, i * 4);
// short off = (short) (i << 2); // i*4
// // 读明文
// getU32(in, (short)(inPos+off), word); // word[0]=lo, word[1]=hi
//
//// putU32(out, i * 4, plain ^ keystream[i]);
// // XOR keystream
// word[0] = (short)(word[0] ^ ks_lo[i]);
// word[1] = (short)(word[1] ^ ks_hi[i]);
// // 写密文
// putU32(out, (short) (outPos+off), word[0], word[1]);
// }
//
// // 调整输入指针和长度
//// int processed = fullBlocks * 4;
// short processed = (short)(fullBlocks * 4);
//
//// byte[] newIn = new byte[inlen - processed];
//// if (inlen - processed > 0) {
//// System.arraycopy(in, processed, newIn, 0, inlen - processed);
//// }
//// in = newIn;
//// inlen -= processed;
// // 推进输入/输出指针与剩余长度
// inPos += processed;
// inlen -= processed;
// outPos += processed;
// }
//
// // 缓存剩余不足4字节的数据
// if (inlen > 0) {
// // 等价于 System.arraycopy(in, 0, this.buf, 0, inlen);
// Util.arrayCopyNonAtomic(in, (short)inPos, this.buf, (short)0, inlen);
//
// this.buflen = inlen;
// }
// }
//
// // 完成加密处理
// public void finishZuc256EncryptCtx(byte[] out) {
// if (out == null) return;
//
// // 处理缓冲区中剩余的不足4字节数据
// if (this.buflen > 0) {
//// int keystream = zuc256GenerateKeyword(this.state);
// // 生成一个 32-bit 密钥字ks[0]=lo16, ks[1]=hi16
// short[] ks = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// zuc256GenerateKeyword(this.state, ks);
//
//// byte[] keystreamBytes = new byte[4];
//// putU32(keystreamBytes, 0, keystream);
// byte[] keystreamBytes = JCSystem.makeTransientByteArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// putU32(keystreamBytes, (short)0, ks[0], ks[1]);
//
// // 逐字节异或
// short outOffset = (short)(out.length - this.buflen);
// for (short i = 0; i < this.buflen; i++) {
// out[(short)(i+outOffset)] = (byte) (this.buf[i] ^ keystreamBytes[i]);
// }
// }
//
//
//
// // 清理上下文
//// Arrays.fill(this.buf, (byte) 0);
// for(short i=0; i<4; i++) {
// this.buf[i] = (byte)0;
// }
//
// this.buflen = 0;
//
//// Arrays.fill(this.state.LFSR, 0);
// // LFSR 全部清零(高低位数组各 16 个元素)
// for (short i = 0; i < 16; i++) {
// this.state.LFSR_lo[i] = 0;
// this.state.LFSR_hi[i] = 0;
// }
//
//
//// this.state.R1 = 0;
//// this.state.R2 = 0;
//// R1、R2 清零
// this.state.R1_lo = 0;
// this.state.R1_hi = 0;
// this.state.R2_lo = 0;
// this.state.R2_hi = 0;
// }
//}

View File

@@ -0,0 +1,32 @@
//package com.cscn;
//
///**
// * MAC上下文类JavaCard版int 拆分为两个 short
// */
//public final class Zuc256MacCtx {
// // LFSR: 原本 int[16],拆成 hi/lo 各 16 short
// short[] LFSR_hi = JCSystem.makeTransientShortArray((short)16, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// //todo -> ram
// short[] LFSR_lo = JCSystem.makeTransientShortArray((short)16, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
//
// // R1、R2: 原本 int拆成 hi/lo
// short R1_hi;
// short R1_lo;
// short R2_hi;
// short R2_lo;
//
// // 缓冲区
// byte[] buf = JCSystem.makeTransientByteArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short buflen;
//
// // T: 原本 int[4],拆成 hi/lo
// short[] T_hi = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] T_lo = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
//
// // K0: 原本 int[4],拆成 hi/lo
// short[] K0_hi = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] K0_lo = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
//
// // macbits: 原本 int改成 short 足够
// short macbits;
//}

View File

@@ -0,0 +1,25 @@
//package com.cscn;
//
///**
// * ZUC状态类JavaCard版int 拆为 hi/lo short
// */
//public class Zuc256State {
// // LFSR: 原 int[16] -> hi/lo 各 16
// public short[] LFSR_hi;
// public short[] LFSR_lo;
//
// // R1, R2: 原 int -> hi/lo
// public short R1_hi;
// public short R1_lo;
// public short R2_hi;
// public short R2_lo;
//
// public Zuc256State() {
// this.LFSR_hi = JCSystem.makeTransientShortArray((short)16, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// this.LFSR_lo = JCSystem.makeTransientShortArray((short)16, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// }
// public Zuc256State(short[] LSFR_HIGH, short[] LSFR_LOW) {
// this.LFSR_hi = LSFR_HIGH;
// this.LFSR_lo = LSFR_LOW;
// }
//}

View File

@@ -0,0 +1,98 @@
package com.cscn;
/**
* 常量表S0/S1 与 ZUC256_D。
* 注意JavaCard 目标环境建议将表定义为 static final 数组,按 int/short 存放。
* 适配说明:已将 32bit int 数组改为 16bit short 数组符合JavaCard 16bit能力要求
*/
public final class Zuc256Tables {
// 私有构造函数:防止类被实例化
private Zuc256Tables() {}
// S盒S0, S1
public static final short[] S0 = {
0x3e,0x72,0x5b,0x47,0xca,0xe0,0x00,0x33,0x04,0xd1,0x54,0x98,0x09,0xb9,0x6d,0xcb,
0x7b,0x1b,0xf9,0x32,0xaf,0x9d,0x6a,0xa5,0xb8,0x2d,0xfc,0x1d,0x08,0x53,0x03,0x90,
0x4d,0x4e,0x84,0x99,0xe4,0xce,0xd9,0x91,0xdd,0xb6,0x85,0x48,0x8b,0x29,0x6e,0xac,
0xcd,0xc1,0xf8,0x1e,0x73,0x43,0x69,0xc6,0xb5,0xbd,0xfd,0x39,0x63,0x20,0xd4,0x38,
0x76,0x7d,0xb2,0xa7,0xcf,0xed,0x57,0xc5,0xf3,0x2c,0xbb,0x14,0x21,0x06,0x55,0x9b,
0xe3,0xef,0x5e,0x31,0x4f,0x7f,0x5a,0xa4,0x0d,0x82,0x51,0x49,0x5f,0xba,0x58,0x1c,
0x4a,0x16,0xd5,0x17,0xa8,0x92,0x24,0x1f,0x8c,0xff,0xd8,0xae,0x2e,0x01,0xd3,0xad,
0x3b,0x4b,0xda,0x46,0xeb,0xc9,0xde,0x9a,0x8f,0x87,0xd7,0x3a,0x80,0x6f,0x2f,0xc8,
0xb1,0xb4,0x37,0xf7,0x0a,0x22,0x13,0x28,0x7c,0xcc,0x3c,0x89,0xc7,0xc3,0x96,0x56,
0x07,0xbf,0x7e,0xf0,0x0b,0x2b,0x97,0x52,0x35,0x41,0x79,0x61,0xa6,0x4c,0x10,0xfe,
0xbc,0x26,0x95,0x88,0x8a,0xb0,0xa3,0xfb,0xc0,0x18,0x94,0xf2,0xe1,0xe5,0xe9,0x5d,
0xd0,0xdc,0x11,0x66,0x64,0x5c,0xec,0x59,0x42,0x75,0x12,0xf5,0x74,0x9c,0xaa,0x23,
0x0e,0x86,0xab,0xbe,0x2a,0x02,0xe7,0x67,0xe6,0x44,0xa2,0x6c,0xc2,0x93,0x9f,0xf1,
0xf6,0xfa,0x36,0xd2,0x50,0x68,0x9e,0x62,0x71,0x15,0x3d,0xd6,0x40,0xc4,0xe2,0x0f,
0x8e,0x83,0x77,0x6b,0x25,0x05,0x3f,0x0c,0x30,0xea,0x70,0xb7,0xa1,0xe8,0xa9,0x65,
0x8d,0x27,0x1a,0xdb,0x81,0xb3,0xa0,0xf4,0x45,0x7a,0x19,0xdf,0xee,0x78,0x34,0x60
};
public static final short[] S1 = {
0x55,0xc2,0x63,0x71,0x3b,0xc8,0x47,0x86,0x9f,0x3c,0xda,0x5b,0x29,0xaa,0xfd,0x77,
0x8c,0xc5,0x94,0x0c,0xa6,0x1a,0x13,0x00,0xe3,0xa8,0x16,0x72,0x40,0xf9,0xf8,0x42,
0x44,0x26,0x68,0x96,0x81,0xd9,0x45,0x3e,0x10,0x76,0xc6,0xa7,0x8b,0x39,0x43,0xe1,
0x3a,0xb5,0x56,0x2a,0xc0,0x6d,0xb3,0x05,0x22,0x66,0xbf,0xdc,0x0b,0xfa,0x62,0x48,
0xdd,0x20,0x11,0x06,0x36,0xc9,0xc1,0xcf,0xf6,0x27,0x52,0xbb,0x69,0xf5,0xd4,0x87,
0x7f,0x84,0x4c,0xd2,0x9c,0x57,0xa4,0xbc,0x4f,0x9a,0xdf,0xfe,0xd6,0x8d,0x7a,0xeb,
0x2b,0x53,0xd8,0x5c,0xa1,0x14,0x17,0xfb,0x23,0xd5,0x7d,0x30,0x67,0x73,0x08,0x09,
0xee,0xb7,0x70,0x3f,0x61,0xb2,0x19,0x8e,0x4e,0xe5,0x4b,0x93,0x8f,0x5d,0xdb,0xa9,
0xad,0xf1,0xae,0x2e,0xcb,0x0d,0xfc,0xf4,0x2d,0x46,0x6e,0x1d,0x97,0xe8,0xd1,0xe9,
0x4d,0x37,0xa5,0x75,0x5e,0x83,0x9e,0xab,0x82,0x9d,0xb9,0x1c,0xe0,0xcd,0x49,0x89,
0x01,0xb6,0xbd,0x58,0x24,0xa2,0x5f,0x38,0x78,0x99,0x15,0x90,0x50,0xb8,0x95,0xe4,
0xd0,0x91,0xc7,0xce,0xed,0x0f,0xb4,0x6f,0xa0,0xcc,0xf0,0x02,0x4a,0x79,0xc3,0xde,
0xa3,0xef,0xea,0x51,0xe6,0x6b,0x18,0xec,0x1b,0x2c,0x80,0xf7,0x74,0xe7,0xff,0x21,
0x5a,0x6a,0x54,0x1e,0x41,0x31,0x92,0x35,0xc4,0x33,0x07,0x0a,0xba,0x7e,0x0e,0x34,
0x88,0xb1,0x98,0x7c,0xf3,0x3d,0x60,0x6c,0x7b,0xca,0xd3,0x1f,0x32,0x65,0x04,0x28,
0x64,0xbe,0x85,0x9b,0x2f,0x59,0x8a,0xd7,0xb0,0x25,0xac,0xaf,0x12,0x03,0xe2,0xf2
};
// /**
// * 常量数组 D16bit short二维数组适配
// */
// public static final short[][] ZUC256_D = {
// {0x22,0x2F,0x24,0x2A,0x6D,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30},
// {0x22,0x2F,0x25,0x2A,0x6D,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30},
// {0x23,0x2F,0x24,0x2A,0x6D,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30},
// {0x23,0x2F,0x25,0x2A,0x6D,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30}
// };
public static final short D_COLS = 16;
/**
* 常量数组 D16bit short二维数组适配
*/
public static final short[] ZUC256_D_FLAT = {
// row 0
0x22,0x2F,0x24,0x2A,0x6D,0x40,0x40,0x40,
0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30,
// row 1
0x22,0x2F,0x25,0x2A,0x6D,0x40,0x40,0x40,
0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30,
// row 2
0x23,0x2F,0x24,0x2A,0x6D,0x40,0x40,0x40,
0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30,
// row 3
0x23,0x2F,0x25,0x2A,0x6D,0x40,0x40,0x40,
0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30
};
/** 读取 D[row][col],返回无符号值 0..255 */
public static short getD(short row, short col) {
// idx = row * 16 + col
short idx = (short)(row * D_COLS + col);
return (short)(ZUC256_D_FLAT[idx] & 0xFF);
}
/** 取一行 (返回一段16个short) */
public static void getDRow(short row, short[] out, short outOff) {
short base = (short)(row * D_COLS);
for (short i = 0; i < D_COLS; i++) {
out[(short)(outOff + i)] = ZUC256_D_FLAT[(short)(base + i)];
}
}
}

View File

@@ -0,0 +1,497 @@
//package com.cscn;
//
//import javacard.framework.Util;
//import javacard.framework.JCSystem;
//
///**
// * 辅助工具:装载/存储、位运算、线性变换、打印等。
// */
//public final class Zuc256Util {
//
// private Zuc256Util() {}
//
//// /** 辅助方法将字节数组转换为32位整数 */
//// public static int getU32(byte[] p, int offset) {
//// return ((p[offset] & 0xFF) << 24) |
//// ((p[offset + 1] & 0xFF) << 16) |
//// ((p[offset + 2] & 0xFF) << 8) |
//// (p[offset + 3] & 0xFF);
//// }
// /** 辅助方法:从字节数组取出 32 位整数,存放到 short[2] (lo, hi) */
// public static void getU32(byte[] p, short offset, short[] out32 /* len=2 */) {
// out32[0] = (short) (((p[(short)(offset + 2)] & 0xFF) << 8) | (p[(short)(offset + 3)] & 0xFF)); //低16位
// out32[1] = (short) (((p[offset] & 0xFF) << 8) | (p[(short)(offset + 1)] & 0xFF)); //高16位
// }
//
//
//// /** 辅助方法将32位整数转换为字节数组 */
//// public static void putU32(byte[] p, int offset, int v) {
//// p[offset] = (byte) (v >> 24);
//// p[offset + 1] = (byte) (v >> 16);
//// p[offset + 2] = (byte) (v >> 8);
//// p[offset + 3] = (byte) v;
//// }
// /** 辅助方法将32位整数(vlo=低16位, vhi=高16位)写入字节数组 */
// public static void putU32(byte[] p, short offset, short vlo, short vhi) {
// // 写高16位
// p[offset] = (byte) ((vhi >> 8) & 0xFF);
// p[(short)(offset + 1)] = (byte) (vhi & 0xFF);
//
// // 写低16位
// p[(short)(offset + 2)] = (byte) ((vlo >> 8) & 0xFF);
// p[(short)(offset + 3)] = (byte) (vlo & 0xFF);
// }
//
//
// // === 31/32 位运算 ===
//
//// /** 31位加法 */
//// public static int add31(int a, int b) {
//// long sum = (long)a + b;
//// return (int) ((sum & 0x7FFFFFFF) + (sum >> 31));
//// }
// /** 31位加法: (a+b) mod (2^31 - 1)
// * 输入: a_lo=低16位, a_hi=高15位
// * b_lo=低16位, b_hi=高15位
// * 输出: out[0]=lo, out[1]=hi
// */
// public static void add31(short a_lo, short a_hi, short b_lo, short b_hi, short[] out /* len==2 */) {
// // ---- 低16位相加 ----
// short lo = (short)(a_lo + b_lo);
// short carry = (short)(
// ( ( (short)( (a_lo & b_lo) | ((a_lo | b_lo) & (short)~lo) ) ) & (short)0x8000 ) != 0
// ? 1 : 0
// );
// // ---- 高15位相加 + 进位 ----
// short hi_raw = (short)((short)((a_hi & 0x7FFF) + (b_hi & 0x7FFF)) + carry);
//
// // 提取第31位hi_raw bit15
// short topbit = (short)((hi_raw >>> 15) & 1);
// short hi = (short)(hi_raw & 0x7FFF); // 保留15位
//
// // ---- 若第31位=1再+1 ----
// if (topbit == 1) {
// short lo2 = (short)(lo + 1);
// short c2 = (short)((lo2 == 0) ? 1 : 0); // lo溢出时进位
// lo = lo2;
// hi = (short)((hi + c2) & 0x7FFF);
// }
//
// out[0] = lo;
// out[1] = hi;
// }
//
//
//// /** 31位旋转 */
//// public static int rot31(int a, int k) {
//// return ((a << k) | (a >>> (31 - k))) & 0x7FFFFFFF;
//// }
// /** 31位循环左移: (a <<< k) mod (2^31 -1)
// * 输入: a_lo=低16位, a_hi=高15位
// * 输出: out[0]=lo, out[1]=hi
// */
// public static void rot31(short a_lo, short a_hi, short k, short[] out /* len==2 */) {
// k = (short)(k % 31); // 限制在 0..30
// if (k == 0) {
// out[0] = a_lo;
// out[1] = (short)(a_hi & 0x7FFF);
// return;
// }
//
// // 拆成 31 位数组 [bit0..bit30]
// short[] bits = JCSystem.makeTransientShortArray((short)31, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// for (short i = 0; i < 16; i++) {
// bits[i] = (short)((a_lo >>> i) & 1);
// }
// for (short i = 0; i < 15; i++) {
// bits[(short)(16 + i)] = (short)((a_hi >>> i) & 1);
// }
//
// // 旋转
// short[] resBits = JCSystem.makeTransientShortArray((short)31, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// for (short i = 0; i < 31; i++) {
// short j = (short)((i + k) % 31);
// resBits[j] = bits[i];
// }
//
// // 拼回 lo, hi
// short lo = 0;
// for (short i = 0; i < 16; i++) {
// lo = (short)(lo | (resBits[i] << i));
// }
// short hi = 0;
// for (short i = 0; i < 15; i++) {
// hi = (short)(hi | (resBits[(short)(16 + i)] << i));
// }
//
// out[0] = lo;
// out[1] = hi;
// }
//
//
//// /** 32位旋转 */
//// public static int rot32(int a, int k) {
//// return (a << k) | (a >>> (32 - k));
//// }
// /** 32位循环左移: (a<<<k) */
// public static void rot32(short a_lo, short a_hi, short k, short[] out /*len==2*/) {
// k = (short)(k & 31); // 0..31
// short lo = a_lo, hi = a_hi, nw_hi, nw_lo;
// while (k > 0) {
// // 先做 1 位循环左移
// // 注意short 在 >>> 时会先提升为 int所以下面都再用 &1 取最低位,避免符号扩展影响
// nw_hi = (short)((hi << 1) | ((lo >>> 15) & 1));
// nw_lo = (short)((lo << 1) | ((hi >>> 15) & 1));
// hi = nw_hi;
// lo = nw_lo;
// k--;
// }
// out[0] = lo; // 低16位
// out[1] = hi; // 高16位
// }
//
//
//// /**
//// * L1函数
//// */
//// public static int L1(int x) {
//// return x ^ rot32(x, 2) ^ rot32(x, 10) ^ rot32(x, 18) ^ rot32(x, 24);
//// }
// /**
// * L1函数: x ^ (x<<<2) ^ (x<<<10) ^ (x<<<18) ^ (x<<<24)
// * 输入: x_lo, x_hi
// * 输出: out[0]=lo, out[1]=hi
// */
// public static void L1(short x_lo, short x_hi, short[] out /*len==2*/) {
// short[] t = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] acc = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
//
// // acc = x
// acc[0] = x_lo;
// acc[1] = x_hi;
//
// // acc ^= rot32(x, 2)
// rot32(x_lo, x_hi, (short)2, t);
// acc[0] ^= t[0];
// acc[1] ^= t[1];
//
// // acc ^= rot32(x, 10)
// rot32(x_lo, x_hi, (short)10, t);
// acc[0] ^= t[0];
// acc[1] ^= t[1];
//
// // acc ^= rot32(x, 18)
// rot32(x_lo, x_hi, (short)18, t);
// acc[0] ^= t[0];
// acc[1] ^= t[1];
//
// // acc ^= rot32(x, 24)
// rot32(x_lo, x_hi, (short)24, t);
// acc[0] ^= t[0];
// acc[1] ^= t[1];
//
// out[0] = acc[0];
// out[1] = acc[1];
// }
//
//
//// /**
//// * L2函数
//// */
//// public static int L2(int x) {
//// return x ^ rot32(x, 8) ^ rot32(x, 14) ^ rot32(x, 22) ^ rot32(x, 30);
//// }
// /**
// * L2函数: x ^ (x<<<8) ^ (x<<<14) ^ (x<<<22) ^ (x<<<30)
// * 输入: x_lo, x_hi
// * 输出: out[0]=lo, out[1]=hi
// */
// public static void L2(short x_lo, short x_hi, short[] out /*len==2*/) {
// short[] t = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] acc = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
//
// // acc = x
// acc[0] = x_lo;
// acc[1] = x_hi;
//
// // acc ^= rot32(x, 8)
// rot32(x_lo, x_hi, (short)8, t);
// acc[0] ^= t[0];
// acc[1] ^= t[1];
//
// // acc ^= rot32(x, 14)
// rot32(x_lo, x_hi, (short)14, t);
// acc[0] ^= t[0];
// acc[1] ^= t[1];
//
// // acc ^= rot32(x, 22)
// rot32(x_lo, x_hi, (short)22, t);
// acc[0] ^= t[0];
// acc[1] ^= t[1];
//
// // acc ^= rot32(x, 30)
// rot32(x_lo, x_hi, (short)30, t);
// acc[0] ^= t[0];
// acc[1] ^= t[1];
//
// out[0] = acc[0];
// out[1] = acc[1];
// }
//
//
//// /** 创建31位无符号整数 */
//// public static int makeU31(int a, int b, int c, int d) {
//// return (((a & 0xFF) << 23) |
//// ((b & 0xFF) << 16) |
//// ((c & 0xFF) << 8) |
//// (d & 0xFF)) & 0x7FFFFFFF;
//// }
// /** 创建31位无符号整数结果放到 out[0]=lo, out[1]=hi(15位) */
// public static void makeU31(short a, short b, short c, short d, short[] out /*len==2*/) {
// // 四个字节
// short b0 = (short)(a & 0xFF); // 最高字节
// short b1 = (short)(b & 0xFF);
// short b2 = (short)(c & 0xFF);
// short b3 = (short)(d & 0xFF); // 最低字节
//
// // 拼成 32 位: b0<<24 | b1<<16 | b2<<8 | b3
// // lo = 低16位
// out[0] = (short)((b2 << 8) | b3);
//
// // hi = 高15位丢弃 bit31
// out[1] = (short)((b0 << 7) | b1);
// }
//
//
//// /** 创建32位无符号整数 */
//// public static int makeU32(int a, int b, int c, int d) {
//// return ((a & 0xFF) << 24) |
//// ((b & 0xFF) << 16) |
//// ((c & 0xFF) << 8) |
//// (d & 0xFF);
//// }
// /** 创建32位无符号整数结果放到 out[0]=lo, out[1]=hi */
// public static void makeU32(short a, short b, short c, short d, short[] out /*len==2*/) {
// // 四个字节
// short b0 = (short)(a & 0xFF); // 最高字节
// short b1 = (short)(b & 0xFF);
// short b2 = (short)(c & 0xFF);
// short b3 = (short)(d & 0xFF); // 最低字节
//
// // lo = 低16位
// out[0] = (short)((b2 << 8) | b3);
//
// // hi = 高16位
// out[1] = (short)((b0 << 8) | b1);
// }
//
//
//
// /** 提取IV */
// public static void extractIv(byte[] input25Byte, byte[] output23Byte) {
// if (input25Byte == null || output23Byte == null) return;
//
// // 复制前17字节
// Util.arrayCopyNonAtomic(input25Byte, (short)0, output23Byte, (short)0, (short)17);
//
//
// // 处理剩余8字节
// byte[] src = JCSystem.makeTransientByteArray((short)8, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// for (short i = 0; i < 8; i++) {
// src[i] = (byte) (input25Byte[(short)(17 + i)] & 0x3F);
// }
//
// output23Byte[17] = (byte) ((src[0] << 2) | (src[1] >>> 4));
// output23Byte[18] = (byte) (((src[1] & 0x0F) << 4) | (src[2] >>> 2));
// output23Byte[19] = (byte) (((src[2] & 0x03) << 6) | src[3]);
// output23Byte[20] = (byte) ((src[4] << 2) | (src[5] >>> 4));
// output23Byte[21] = (byte) (((src[5] & 0x0F) << 4) | (src[6] >>> 2));
// output23Byte[22] = (byte) (((src[6] & 0x03) << 6) | src[7]);
// }
//
// /**
// * 32位加法: (a_hi:a_lo) + (b_hi:b_lo)
// * out[0] = lo, out[1] = hi
// */
// static void add32(short a_lo, short a_hi,
// short b_lo, short b_hi,
// short[] out /*len=2*/) {
//
// // ---- 低16位 ----
// short lo_low = (short)((a_lo & 0x00FF) + (b_lo & 0x00FF));
// short carry0 = (short)(((a_lo & 0x00FF) + (b_lo & 0x00FF)) >>> 8);
//
// short a_lo_hi = (short)((a_lo >>> 8) & 0x00FF);
// short b_lo_hi = (short)((b_lo >>> 8) & 0x00FF);
// short lo_high = (short)(a_lo_hi + b_lo_hi + carry0);
// short carry1 = (short)(lo_high >>> 8);
//
// short lo_res = (short)((lo_high << 8) | (lo_low & 0x00FF));
//
// // ---- 高16位 ----
// short hi_low = (short)((a_hi & 0x00FF) + (b_hi & 0x00FF) + carry1);
// short carry2 = (short)(hi_low >>> 8);
//
// short a_hi_hi = (short)((a_hi >>> 8) & 0x00FF);
// short b_hi_hi = (short)((b_hi >>> 8) & 0x00FF);
// short hi_high = (short)(a_hi_hi + b_hi_hi + carry2);
//
// short hi_res = (short)((hi_high << 8) | (hi_low & 0x00FF));
//
// // ---- 输出 ----
// out[0] = lo_res;
// out[1] = hi_res;
// }
//
// /**
// * 32位加法 + 返回进位(只用 short
// * 输入: (a_hi:a_lo) + (b_hi:b_lo)
// * 输出: out[0]=lo, out[1]=hi
// * 返回: 最终进位(0/1)
// */
// static short add32_with_carry(short a_lo, short a_hi,
// short b_lo, short b_hi,
// short[] out /* len=2 */) {
// // ---- 低16位分两段8位相加 ----
// short s0 = (short)((a_lo & (short)0x00FF) + (b_lo & (short)0x00FF)); // 0..510
// short c0 = (short)(s0 >>> 8); // 0/1
// short s1 = (short)(((a_lo >>> 8) & (short)0x00FF)
// + ((b_lo >>> 8) & (short)0x00FF)
// + c0); // 0..511
// short c1 = (short)(s1 >>> 8); // 0/1
// short lo = (short)((s1 << 8) | (s0 & (short)0x00FF));
//
// // ---- 高16位再分两段8位相加并加上 c1 ----
// short s2 = (short)((a_hi & (short)0x00FF) + (b_hi & (short)0x00FF) + c1);
// short c2 = (short)(s2 >>> 8); // 0/1
// short s3 = (short)(((a_hi >>> 8) & (short)0x00FF)
// + ((b_hi >>> 8) & (short)0x00FF)
// + c2); // 0..511
// short c3 = (short)(s3 >>> 8); // 最终进位 0/1
// short hi = (short)((s3 << 8) | (s2 & (short)0x00FF));
//
// out[0] = lo;
// out[1] = hi;
// return (short)(c3 & 1);
// }
//
//
//
// /**
// * 64位加法: a4 + b4 -> a4
// * 输入输出: short[4],低到高 (a[0]=lo16, a[1]=hi16, a[2]=lo16 of high dword, a[3]=hi16 of high dword)
// */
// static void add64(short[] a, short[] b) {
// short[] tmp = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
//
// // 低 32 位
// short carry = add32_with_carry(a[0], a[1], b[0], b[1], tmp);
// a[0] = tmp[0];
// a[1] = tmp[1];
//
// // 高 32 位 + carry
// add32((short)(a[2] + (short)(carry & (short)0x0001)), a[3], b[2], b[3], tmp);
// a[2] = tmp[0];
// a[3] = tmp[1];
// }
//
//
//
// // 32位异或
// public static void xor32(short a_lo, short a_hi, short b_lo, short b_hi, short[] out /*len==2*/) {
// out[0] = (short)(a_lo ^ b_lo);
// out[1] = (short)(a_hi ^ b_hi);
// }
//
// /**
// * 把32位数 b (b[0]=lo, b[1]=hi) 左移 k 位 (0 <= k < 32)
// * 结果放到64位数 a (a[0]=最低16位 ... a[3]=最高16位)。
// */
// static void create_64b_from_32b(short[] a/*len=4*/, short[] b/*len=2*/, short k) {
// short a0 = b[0], a1 = b[1], a2 = 0, a3 = 0;
//
// if (k >= 16) {
// a3 = a2; // 0
// a2 = a1; // 原 hi16
// a1 = a0; // 原 lo16
// a0 = 0;
// k = (short)(k - 16);
// }
//
// while (k > 0) {
// short c0 = (short)((a0 >>> 15) & 1);
// short c1 = (short)((a1 >>> 15) & 1);
// short c2 = (short)((a2 >>> 15) & 1);
//
// a3 = (short)((a3 << 1) | c2);
// a2 = (short)((a2 << 1) | c1);
// a1 = (short)((a1 << 1) | c0);
// a0 = (short)(a0 << 1);
// k--;
// }
//
// a[0] = a0; a[1] = a1; a[2] = a2; a[3] = a3;
// }
//
//
// /**
// * (A & 0x7FFFFFFF),结果放在 out[4]只保留低32位并清掉最高bit。
// */
// static void and64_7FFFFFFF_to32(short[] A, short[] out) {
// out[0] = A[0]; // lo16
// out[1] = (short)(A[1] & 0x7FFF); // hi16 (清除最高bit)
// out[2] = 0;
// out[3] = 0;
// }
//
// /**
// * 64位无符号右移 31 位
// * 输入: A[0..3] (short[4], A[0]最低16位)
// * 输出: out[0..3]
// */
// static void shr64u_31(short[] A, short[] out) {
// // 先拼出 64bit 的逻辑,逐段右移
// // A >>> 31 = (A >>> 16) >>> 15
//
// // 先右移 16相当于丢掉 A[0],整体右移一半字
// out[0] = A[1]; // 原 A[1] -> 新低16位
// out[1] = A[2]; // 原 A[2]
// out[2] = A[3]; // 原 A[3]
// out[3] = 0; // 高位补0
//
// // 再右移 15 位
// short c0 = (short)((out[0] & (short)0xFFFF) >>> 15); // out[0] 最后一位变进位
// short c1 = (short)((out[1] & (short)0xFFFF) >>> 15);
// short c2 = (short)((out[2] & (short)0xFFFF) >>> 15);
//
// out[0] = (short)((c0 & 0x0001) | (out[1] << 1));
// out[1] = (short)((c1 & 0x0001) | (out[2] << 1));
// out[2] = (short)(c2 & 0x0001);
// }
//
// /**
// * 32位无符号右移 1 位
// * 输入: lo,hi (short) 表示 32 位数 (hi:高16位, lo:低16位)
// * 输出: out[0]=lo, out[1]=hi
// */
// static void shr32u1(short lo, short hi, short[] out) {
// // >>>1先处理低16位
// short nwLo = (short)(((((lo & (short)0xFFFF) >>> 1) & (short)0x7FFF)) | ((hi & 0x0001) << 15));
// short nwHi = (short)(((hi & (short)0xFFFF) >>> 1) & (short)0x7FFF);
//
// out[0] = nwLo;
// out[1] = nwHi;
// }
//
//
//
//
// /** 打印/*十六进制调试用TODO 生产/JC 环境可移除) *//*
// public static void printHex(String label, byte[] data, int len) {
// System.out.print(label + ": ");
// for (int i = 0; i < len; i++) {
// System.out.printf("%02x ", data[i] & 0xFF);
// }
// System.out.println();
// }*/
//}

Binary file not shown.

Binary file not shown.

Binary file not shown.

3
build_tools/Tools/ext_api/gp221/.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/gp221.iml" filepath="$PROJECT_DIR$/gp221.iml" />
</modules>
</component>
</project>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
</set>
</option>
</component>
</project>

View File

@@ -0,0 +1,3 @@
Manifest-Version: 1.0
Created-By: 1.6.0_30 (Sun Microsystems Inc.)

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -0,0 +1,77 @@
package org.globalplatform;
import javacard.framework.*;
/**
* This interface defines a method through which an Application may forward
* input data to another Application.<p>
*
* This interface shall be implemented by an Application that wishes to receive
* personalization data forwarded by its associated Security Domain. In such a
* scenario, if the Application implements both the {@link Application} and the
* {@link Personalization} interface, then the Security Domain shall use the
* {@link Personalization} interface. <p>
*
* @see Personalization
*
* @since export file version 1.0
*/
public interface Application extends Shareable
{
/**
* Processes application specific data received from another on-card entity.<p>
*
* If the Application invoking this method is a Security Domain then it shall
* be assumed that:<ul>
*
* <li>The <code>baBuffer</code> byte array is a <em>global</em> byte array;
*
* <li>The data forwarded by the Security Domain is a STORE DATA command. The
* <code>sOffset</code> parameter locates the class byte of the command and
* the <code>sLength</code> parameter indicates the length of the entire
* command (i.e. header + data field).
*
* <li>Any exception thrown by this method will be rethrown by the Security
* Domain, hence will be converted to and returned as a response status word
* to the off-card entity. If the exception is an {@link ISOException}, then
* the status word will be the reason code of that exception. Otherwise, a
* status word of '6F00' will be returned.
*
* </ul>
*
* <p>Notes:<ul>
*
* <li><em>Upon invocation of this method, the Java Card VM performs a
* context switch.</em>
*
* <li><em>As the Application is not the currently selected Application, it
* should not attempt to access transient memory of type
* <code>CLEAR_ON_DESELECT</code> during the processing of this method.</em>
*
* <li><em>The Application is responsible for managing the atomic
* modification of its own data, if needed.</em>
*
* <li><em>As this method may be invoked by a Security Domain immaterial of
* the Application's internal state, the Application is responsible for
* ensuring that its internal state is valid for this operation.</em>
*
* </ul>
*
* @param baBuffer byte array containing input data. Must be a
* <em>global</em> byte array.
* @param sOffset offset of input data within <code>baBuffer</code>.
* @param sLength length of input data.
*
* @exception SecurityException if <code>baBuffer</code> is not a
* <em>global</em> byte array.
* @exception NullPointerException if <code>baBuffer</code> is <code>null</code>.
* @exception ArrayIndexOutOfBoundsException if reading input data would
* cause access of data outside array bounds.
*/
public abstract void processData(byte[] baBuffer, short sOffset, short sLength);
}

View File

@@ -0,0 +1,131 @@
package org.globalplatform;
import javacard.framework.Shareable;
import javacard.security.CryptoException;
/**
* This interface allows performing operations such as recovering a
* cryptographic key or signing data. The required algorithms and credentials
* are known implicitly.<p>
*
* It is intended that Security Domains would be able to access an {@link
* Authority} instance through a Global Service by a Controlling Authority
* Security Domain (CASD) with a service name of <code>({@link
* GPSystem#FAMILY_AUTHORITY}<<8|0x00)</code>.<p>
*
* @since <ul>
* <li>export file version 1.2: initial version.
* <li>export file version 1.6: reviewed overall description of this interface.
* </ul>
*/
public interface Authority extends Shareable
{
/**
* Used with {@link #init} method to indicate signing mode.
*/
public final byte MODE_SIGN=1;
/**
* Used with {@link #init} method to indicate key recovery mode.
*/
public final byte MODE_KEY_RECOVERY=2;
/**
* Initializes the Authority interface with the appropriate mode (<code>MODE_SIGN</code> or <code>MODE_KEY_RECOVERY</code>).
*
* @param theMode one of {@link #MODE_SIGN} or {@link #MODE_KEY_RECOVERY}.
*
* @exception CryptoException with the following reason code:<ul>
* <li><code>ILLEGUAL_VALUE</code> if theMode option is an undefined
* value.</ul>
*/
public void init(byte theMode) throws CryptoException;
/**
* Generates the signature of all/last input data.
* A call to this method resets this Authority interface to the state it was
* in when previously initialized via a call to init().
* That is, the object is reset and available to sign another message.
* The input and output buffer may overlap and shall be <em>global</em> arrays.
*
* @param inBuff the input buffer of data to be signed
* @param inOffset the offset in input buffer at which the signature starts
* @param inLength the byte length to sign
* @param sigBuff the output buffer to store signature data
* @param sigOffset the offset into sigBuff at which to begin signature generation
*
* @return the number of bytes of signature output in sigBuff
*
* @throws CryptoException with the following reason codes:<ul>
* <li><code>INVALID_INIT</code> if this Authority interface is not initialized or
* initialized in <code>MODE_KEY_RECOVERY</code> mode.
* <li><code>ILLEGAL_USE</code> if this Authority algorithm does not pad the message and
* the message is not block aligned.</ul>
* @throws SecurityException if the inBuff or sigBuff are not <em>global</em> arrays.
*/
public short sign(byte[] inBuff,
short inOffset,
short inLength,
byte[] sigBuff,
short sigOffset)
throws CryptoException;
/**
* Accumulates input data. for the current operation (<code>MODE_SIGN</code> or <code>MODE_KEY_RECOVERY</code>).
* <p>
* When this method is used, temporary storage of intermediate results is required.
* This method should only be used if all the input data required for the current operation
* is not available in one byte array.
* The <code>sign</code> or <code>recoverKey</code> methods are recommended whenever possible.
* The inBuff shall be <em>global</em> array.
*
* @param inBuff buffer containing input data
* @param inOffset offset of input data
* @param inLength length of input data
* @throws CryptoException with the following reason codes:<ul>
* <li><code>INVALID_INIT</code> if this Authority interface is not initialized.</ul>
* @throws SecurityException if the inBuff is not <em>global</em> array.
*/
public void update(byte[] inBuff,
short inOffset,
short inLength)
throws CryptoException;
/**
* Recovers a cryptographic key from a set of data
* structures provided in the input buffer (inBuff).
* As a mandatory step, the recovery mechanism includes the verification of
* the origin and integrity of the recovered key.
* This method knows, from the set of data structures present in the input
* buffer, which recovery mechanism is to be used.
* The recovered key is written in the ouput buffer (outBuff) at specified
* offset (outOffset), in the form of a key data structure whose format
* depends on the type of the key.
* A call to this method resets this instance of the Authority interface to
* the state it was in when previously initialized via a call to init().
* That is, the object is reset and available to recover another key.
* The input and output buffers may overlap and shall be <em>global</em> arrays.
*
* @param inBuff containing input data.
* @param inOffset offset of input data.
* @param inLength length of input data.
* @param outBuff the buffer where recovered key data structure shall be written
* @param outOffset offset where recovered key data structure shall be written
* @return <code>Length</code> of the recovered key data structure written
* in outBuff at outOffset,or 0 if the recovery mechanism failed
* (e.g. recovered key was considered invalid).
*
* @throws CryptoException - with the following reason codes:<ul>
* <li><code>INVALID_INIT</code> if this Authority interface is not initialized or
* initialized in <code>MODE_SIGN</code> mode.</ul>
* @throws SecurityException if the inBuff or outBuff are not <em>global</em> arrays.
*/
public short recoverKey(byte[] inBuff,
short inOffset,
short inLength,
byte[] outBuff,
short outOffset)
throws CryptoException;
}

View File

@@ -0,0 +1,343 @@
package org.globalplatform;
import javacard.framework.*;
/**
* This interface defines basic Cardholder Verification Method services
* (e.g. comparison of CVM value, CVM state query). It is typically exposed to
* on-card Applications by a Global Services Application implementing one or
* more Cardholder Verification Methods. Some services are restricted to
* Applications having the CVM Management Privilege.<p>
*
* To retrieve an instance of this interface, an Application shall invoke the
* {@link GPSystem#getCVM} method, or shall use a {@link GlobalService} instance
* of the {@link GPSystem#FAMILY_CVM} family. For backward compatibility, the
* {@link CVM} instances retrieved using the {@link GPSystem#getCVM} method are
* mapped onto those retrieved as Global Services of the {@link
* GPSystem#FAMILY_CVM} family.<p>
*
* The CVM instance maintains the following data (see Card Specification v2.2.1
* section 8.2.2 for more details):<ul>
*
* <li>CVM state: ACTIVE, INVALID_SUBMISSION, VALIDATED or BLOCKED. In addition,
* we distinguish the case where the CVM instance is not fully initialized
* (i.e. either the CVM value or the CVM try limit has not been set) and has
* never entered the state ACTIVE.
*
* <li>CVM try limit: the maximum value of the CVM try counter.
*
* <li>CVM try counter: the number of unsuccessful comparisons of the CVM value
* that may be performed before this CVM instance gets blocked.
*
* <li>CVM value: the secret value held by this CVM instance, stored in ASCII,
* BCD or HEX format.
*
* </ul>
*
* Operations performed by this interface shall be independent of, and not
* interfere with, any transaction in progress (e.g. if the {@link #verify}
* method is invoked from within a transaction and this transaction is aborted,
* then the try counter is not revert to its original value).<p>
*
* @since <ul>
* <li>export file version 1.0: initial version.
* <li>export file version 1.6: reviewed overall description of this interface.
* </ul>
*/
public interface CVM extends Shareable
{
/**
* The CVM value comparison was successful.
*/
public static final short CVM_SUCCESS = 0;
/**
* The CVM value comparison failed.
*/
public static final short CVM_FAILURE = -1;
/**
* The CVM value is formatted as ASCII bytes.<p>
*
* Note:<ul> <li><em>If the CVM value is stored in a format other than ASCII,
* it is the responsibility of the interface to convert to the expected
* format.</em> </ul>
*/
public static final byte FORMAT_ASCII = (byte) 0x01;
/**
* The CVM value is formatted as numerical digits, coded on a nibble (4 bits)
* and left justified.<p>
*
* Note:<ul> <li><em>If the CVM value is stored in a format other than BCD,
* it is the responsibility of the interface to convert to the expected
* format.</em>
* <li><em>If the length of the CVM value is odd, the right most nibble of
* the CVM value shall be high values ('F').</em> </ul>
*/
public static final byte FORMAT_BCD = (byte) 0x02;
/**
* The CVM value is formatted as hexadecimal (binary) data.<p>
*
* Note:<ul> <li><em>If the CVM value is stored in a format other than HEX,
* it is the responsibility of the interface to convert to the expected
* format.</em> </ul>
*/
public static final byte FORMAT_HEX = (byte) 0x03;
/**
* Indicates whether this CVM instance is active, that is, whether it has
* been fully initialized (i.e. both value and try limit) and is ready
* for use. If yes, then the CVM state is deemed to be in one of the
* following states: ACTIVE, INVALID_SUBMISSION, VALIDATED or BLOCKED.<p>
*
* @return <code>true</code> if the CVM has been fully initialized and is
* ready for use, <code>false</code> otherwise (i.e. the CVM state is NOT_READY).
*/
public boolean isActive();
/**
* Indicates whether an attempt has been made to compare the CVM value, that
* is, whether the CVM state is INVALID_SUBMISSION or VALIDATED.<p>
*
* @return <code>true</code> if the CVM state is INVALID_SUBMISSION or
* VALIDATED, <code>false</code> otherwise.
*/
public boolean isSubmitted();
/**
* Indicates whether a successful comparison of the CVM value has occurred,
* that is, whether the CVM state is VALIDATED.<p>
*
* @return <code>true</code> if the CVM state is VALIDATED,
* <code>false</code> otherwise.
*/
public boolean isVerified();
/**
* Indicates whether this CVM instance is blocked, that is, whether the CVM
* state is BLOCKED.<p>
*
* @return <code>true</code> if the CVM state is BLOCKED, <code>false</code>
* otherwise.
*/
public boolean isBlocked();
/**
* Gets the CVM try counter, that is, the number of unsuccessful comparisons
* of the CVM value that may be performed before this CVM instance gets
* blocked.<p>
*
* @return current value of the CVM try counter.
*/
public byte getTriesRemaining();
/**
* Updates the CVM value.<p>
*
* If the Application invoking this method does not have the CVM Management
* Privilege, or if the specified format (<code>bFormat</code>) is unknown
* (or not supported by this CVM instance), or if the new CVM value is not
* consistent with respect to the specified format, then the CVM value is not
* updated.<p>
*
* If the CVM value is successfully updated and the CVM try limit has already
* been successfully set previously, then this method also resets the CVM try
* counter to the CVM try limit, and (re)sets the CVM state to ACTIVE.<p>
*
* Notes:<ul>
*
* <li><em>If the Global Service Application providing this CVM instance has
* the Global Registry Privilege, it is able to check that the Application
* invoking this method has the CVM Management Privilege using the {@link
* GPRegistryEntry} interface;</em>
*
* <li><em>The CVM instance shall record the format, length, and value of the
* CVM value.</em>
*
* </ul>
*
* @param baBuffer byte array containing the new CVM value. Must be a
* <em>global</em> byte array.
* @param sOffset offset of the new CVM value within <code>baBuffer</code>.
* @param bLength length of the new CVM value.
* @param bFormat format of the new CVM value: {@link #FORMAT_ASCII}, {@link
* #FORMAT_BCD} or {@link #FORMAT_HEX}.
*
* @return <code>true</code> if the CVM value was successfully updated,
* <code>false</code> otherwise.
*
* @see GPRegistryEntry#PRIVILEGE_CVM_MANAGEMENT
*
* @exception SecurityException if <code>baBuffer</code> is not a
* <em>global</em> byte array.
* @exception NullPointerException if <code>baBuffer</code> is <code>null</code>.
* @exception ArrayIndexOutOfBoundsException if reading the new CVM value
* would cause access of data outside array bounds.
*/
public boolean update(byte[] baBuffer, short sOffset, byte bLength, byte bFormat);
/**
* Resets the CVM state to ACTIVE.<p>
*
* The CVM state can only be reset to ACTIVE from the states ACTIVE,
* INVALID_SUBMISSION or VALIDATED. In particular, it cannot be reset to
* ACTIVE if it is in state BLOCKED or if the CVM instance never entered the
* state ACTIVE, that is, if the CVM instance is not fully
* initialized.<p>
*
* @return <code>true</code> if the CVM state was reset, <code>false</code> otherwise.
*/
public boolean resetState();
/**
* Sets the CVM state to BLOCKED.<p>
*
* If the Application invoking this method does not have the CVM Management
* Privilege, then the CVM state is not updated.<p>
*
* The CVM state can only be set to BLOCKED if the CVM instance already
* entered the state ACTIVE once, that is, if the CVM instance is fully
* initialized. Notice that this method shall return <code>true</code> if the
* CVM state is already BLOCKED. <p>
*
* Notes:<ul>
* <li><em>If the Global Service Application providing this CVM instance has
* the Global Registry Privilege, it is able to check that the Application
* invoking this method has the CVM Management Privilege using the {@link
* GPRegistryEntry} interface;</em>
* </ul>
*
* @return <code>true</code> if the CVM state was set to BLOCKED,
* <code>false</code> otherwise.
*
* @see GPRegistryEntry#PRIVILEGE_CVM_MANAGEMENT
*/
public boolean blockState();
/**
* Resets the CVM state to ACTIVE, even if it is currently BLOCKED.<p>
*
* If the Application invoking this method does not have the CVM Management
* Privilege, then the CVM state is not updated.<p>
*
* The CVM state can only be set to ACTIVE if the CVM instance already
* entered the state ACTIVE once, that is, if the CVM instance is fully
* initialized.
*
* If the CVM state is successfully reset, then this method also resets the
* CVM try counter to the CVM try limit.<p>
*
* Notes:<ul>
* <li><em>If the Global Service Application providing this CVM instance has
* the Global Registry Privilege, it is able to check that the Application
* invoking this method has the CVM Management Privilege using the {@link
* GPRegistryEntry} interface;</em>
* </ul>
*
* @return <code>true</code> if the CVM state was reset to ACTIVE,
* <code>false</code> otherwise.
*
* @see GPRegistryEntry#PRIVILEGE_CVM_MANAGEMENT
*/
public boolean resetAndUnblockState();
/**
* Sets the CVM try limit, that is, the maximum value of the CVM try
* counter.<p>
*
* If the Application invoking this method does not have the CVM Management
* Privilege, then the CVM try limit is not set.<p>
*
* If the CVM try limit is successfully set, then this method also resets the
* CVM try counter to the new CVM try limit. If the CVM value has already
* been successfully set previously, then this method also (re)sets the CVM
* state to ACTIVE.<p>
*
* Notes:<ul>
* <li><em>If the Global Service Application providing this CVM instance has
* the Global Registry Privilege, it is able to check that the Application
* invoking this method has the CVM Management Privilege using the {@link
* GPRegistryEntry} interface;</em>
* </ul>
*
* @param bTryLimit the maximum number of tries for the CVM.
*
* @return <code>true</code> if the try limit was set, <code>false</code>
* otherwise.
*
* @see GPRegistryEntry#PRIVILEGE_CVM_MANAGEMENT
*/
public boolean setTryLimit(byte bTryLimit);
/**
* Compares a value with the stored CVM value.<p>
*
* If the CVM state is BLOCKED, or if the submitted format
* (<code>bFormat</code>) is unknown (or not supported by this CVM instance),
* or if this method throws a {@link NullPointerException} or an {@link
* ArrayIndexOutOfBoundsException}, then the comparison is deemed
* unsuccessful.<p>
*
* If the submitted CVM value is not in the same format as the stored CVM
* value, then format conversion shall occur according to the following rules
* prior to comparing values:<ul>
*
* <li>If HEX format is submitted and the stored CVM value is in ASCII or BCD
* format, then the conversion cannot occur and the comparison is deemed
* unsuccessful;
*
* <li>If BCD or ASCII format is submitted and the stored CVM value is in HEX
* format, then the conversion cannot occur and the comparison is deemed
* unsuccessful;
*
* <li>If ASCII format is submitted and the stored CVM value is in BCD
* format, then conversion can occur if the submitted CVM value only contains
* numerical ASCII characters: the numeric characters (coded on one byte) of
* the submitted value are converted to numeric nibbles, padded together in
* bytes, and a padding nibble 'F' is added on the right if necessary.
* Otherwise, the conversion cannot occur and the comparison is deemed
* unsuccessful;
*
* <li>If BCD format is submitted and the stored CVM value is in ASCII
* format, then conversion can occur if the stored CVM value only contains
* numerical ASCII characters: the numeric nibbles of the submitted value are
* expanded to the corresponding characters coded on one byte and the padding
* nibble 'F' is deleted (if present). Otherwise, the conversion cannot occur
* and the comparison is deemed unsuccessful; </ul>
*
* If the comparison is unsuccessful and the CVM state is not BLOCKED, then
* the CVM try counter must be decremented (by 1). In this case, if the CVM
* try counter reaches a value of '0' then the CVM state shall be set to
* BLOCKED, otherwise the CVM state shall be set to INVALID_SUBMISSION.<p>
*
* If the comparison is successful, then the CVM try counter shall be reset
* to the CVM try limit and the CVM state shall be set to VALIDATED.<p>
*
* The CVM try counter and the CVM state shall not conform to a transaction
* in progress, i.e. they shall not revert to a previous value if a
* transaction in progress is aborted.<p>
*
* @param baBuffer byte array containing the submitted CVM value. Must be a
* <em>global</em> byte array.
* @param sOffset offset of the submitted CVM value within <code>baBuffer</code>.
* @param bLength length of the submitted CVM value.
* @param bFormat format of the submitted CVM value: {@link #FORMAT_ASCII},
* {@link #FORMAT_BCD} or {@link #FORMAT_HEX}.
*
* @return {@link #CVM_SUCCESS} if the comparison was successful, {@link
* #CVM_FAILURE} otherwise.
*
* @exception SecurityException if <code>baBuffer</code> is not a
* <em>global</em> byte array.
* @exception NullPointerException if <code>baBuffer</code> is <code>null</code>.
* @exception ArrayIndexOutOfBoundsException if reading the submitted CVM
* value would cause access of data outside array bounds.
*/
public short verify(byte[] baBuffer, short sOffset, byte bLength, byte bFormat);
}

View File

@@ -0,0 +1,347 @@
package org.globalplatform;
import javacard.framework.*;
/**
* This interface allows querying and potentially modifying the registry data of
* an Application registered within the GlobalPlatform Registry.<p>
*
* Every {@link GPRegistryEntry} instance to an Application registered within
* the GlobalPlatform Registry.<p>
*
* To retrieve an instance of this interface, an Application shall invoke the
* {@link GPSystem#getRegistryEntry} method.<p>
*
* @since <ul>
* <li>export file version 1.1: initial version.
* <li>export file version 1.6: reviewed overall description of this interface.
* </ul>
*/
public interface GPRegistryEntry extends Shareable
{
/**
* Privilege indicating Authorized Management (0x09).
*/
public static final byte PRIVILEGE_AUTHORIZED_MANAGEMENT = (byte) 0x09;
/**
* Privilege indicating Card Lock (0x03).
*/
public static final byte PRIVILEGE_CARD_LOCK = (byte) 0x03;
/**
* Privilege indicating Card Reset (0x05).
*/
public static final byte PRIVILEGE_CARD_RESET = (byte) 0x05;
/**
* Privilege indicating Card Terminate (0x04).
*/
public static final byte PRIVILEGE_CARD_TERMINATE = (byte) 0x04;
/**
* Privilege indicating CVM Management (0x06).
*/
public static final byte PRIVILEGE_CVM_MANAGEMENT = (byte) 0x06;
/**
* Privilege indicating DAP verification (0x01).
*/
public static final byte PRIVILEGE_DAP_VERIFICATION = (byte) 0x01;
/**
* Privilege indicating Delegated Management (0x02).
*/
public static final byte PRIVILEGE_DELEGATED_MANAGEMENT = (byte) 0x02;
/**
* Privilege indicating Final Application (0x0E).
*/
public static final byte PRIVILEGE_FINAL_APPLICATION = (byte) 0x0E;
/**
* Privilege indicating Global Delete (0x0B).
*/
public static final byte PRIVILEGE_GLOBAL_DELETE = (byte) 0x0B;
/**
* Privilege indicating Global Lock (0x0C).
*/
public static final byte PRIVILEGE_GLOBAL_LOCK = (byte) 0x0C;
/**
* Privilege indicating Global Registry (0x0D).
*/
public static final byte PRIVILEGE_GLOBAL_REGISTRY = (byte) 0x0D;
/**
* Privilege indicating Global Service (0x0F).
*/
public static final byte PRIVILEGE_GLOBAL_SERVICE = (byte) 0x0F;
/**
* Privilege indicating Mandated DAP verification privilege (0x07).
*/
public static final byte PRIVILEGE_MANDATED_DAP = (byte) 0x07;
/**
* Privilege indicating Receipt Generation (0x10).
*/
public static final byte PRIVILEGE_RECEIPT_GENERATION = (byte) 0x10;
/**
* Privilege indicating application is a Security Domain (0x00).
*/
public static final byte PRIVILEGE_SECURITY_DOMAIN = (byte) 0x00;
/**
* Privilege indicating Token Verification (0x0A).
*/
public static final byte PRIVILEGE_TOKEN_VERIFICATION = (byte) 0x0A;
/**
* Privilege indicating Trusted Path (0x08).
*/
public static final byte PRIVILEGE_TRUSTED_PATH = (byte) 0x08;
/**
* Privilege indicating Ciphered Load File Data Block (0x11).
*/
public static final byte PRIVILEGE_CIPHERED_LOAD_FILE_DATA_BLOCK = (byte) 0x11;
/**
* Deregisters a service name.<p>
*
* The OPEN shall check that the Application invoking this method corresponds
* to <code>this</code> entry, that it has the Global Service Privilege, and
* that the specified service name was previously uniquely registered by that
* same Application. If not, this method shall throw an exception (see
* below).<p>
*
* @param sServiceName the service name that shall be deregistered.<p>
*
* A service name is encoded on 2 bytes, the 1st byte identifying a family of
* services and the 2nd byte identifying a service within that family.<p>
*
* The {@link GPSystem} class defines a set of constants
* <code>FAMILY_XXX</code> (of the <code>byte</code> type) that may be used to
* build a service name (of the <code>short</code> type) suitable to invoke
* this method as shown in the following examples:<ul>
*
* <li><code>(short)(({@link GPSystem#FAMILY_CVM}<<8)|0x11)</code>
*
* <li><code>(short)(({@link GPSystem#FAMILY_HTTP_ADMINISTRATION}<<8)|0x00)</code>
*
* </ul>
*
* @exception ISOException if this method is not supported or if the service
* name was not found or if the conditions allowing to deregister the service
* name are not satisfied.
*
* @see #registerService
* @see GPSystem#FAMILY_CVM
* @see GPSystem#FAMILY_SECURE_CHANNEL
* @see GPSystem#FAMILY_USSM
* @see GPSystem#FAMILY_AUTHORITY
* @see GPSystem#FAMILY_HTTP_ADMINISTRATION
* @see GPSystem#FAMILY_HTTP_REPORT
*/
public void deregisterService(short sServiceName) throws ISOException;
/**
* Gets the AID of the Application corresponding to <code>this</code> entry.
*
* @return {@link AID} instance identifying the Application corresponding to
* <code>this</code> entry.
*/
public AID getAID();
/**
* Gets the Privilege Bytes of the Application corresponding to
* <code>this</code> entry.
*
* @param baBuffer byte array where Privileges Bytes shall be written.
* @param sOffset offset within <code>baBuffer</code> where Privileges Bytes
* shall be written.
*
* @return <code>sOffset</code> + number of Privilege Bytes written to
* <code>baBuffer</code>.
*
* @exception SecurityException if <code>baBuffer</code> is not accessible in
* the caller's context e.g. <code>baBuffer</code> is not a <em>global</em>
* array nor an array belonging to the caller context.
* @exception NullPointerException if <code>baBuffer</code> is <code>null</code>.
* @exception ArrayIndexOutOfBoundsException if writing Privileges Bytes would
* cause access of data outside array bounds.
*/
public short getPrivileges(byte[] baBuffer, short sOffset) throws ArrayIndexOutOfBoundsException;
/**
* Gets the Life Cycle State of the Application corresponding to
* <code>this</code> entry.
*
* @return the Life Cycle State of the Application corresponding to
* <code>this</code> entry.
*/
public byte getState();
/**
* Checks whether the Application corresponding to <code>this</code> entry is
* associated with the specified Security Domain.<p>
*
* The OPEN shall check that the specified <code>sdAID</code> indeed
* identifies a Security Domain present on the card, and check that the
* Application corresponding to <code>this</code> entry is associated with
* this Security Domain. If not, this method shall return
* <code>false</code>.<p>
*
* @param sdAID AID of a Security Domain.
*
* @return <code>true</code> if the Application corresponding to
* <code>this</code> entry is associated with the specified Security Domain,
* <code>false</code> otherwise.
*/
public boolean isAssociated(AID sdAID);
/**
* Checks whether the Application corresponding to <code>this</code> entry has
* the specified privilege.<p>
*
* If the specified privilege is unknown, this method shall return
* <code>false</code>.
*
* @param bPrivilege the privilege number to check, i.e. one of the
* <code>PRIVILEGE_XXX</code> constants.
*
* @return <code>true</code> if the Application corresponding to
* <code>this</code> entry has the specified privilege, <code>false</code>
* otherwise.
*/
public boolean isPrivileged(byte bPrivilege);
/**
* Registers a service name identifying a service provided by the Application
* corresponding to <code>this</code> entry.<p>
*
* The specified service name (<code>sServiceName</code>) shall be unique
* among all the service names previously registered in the GlobalPlatform
* Registry using this method. Following successful invocation of this method,
* this service name is known to be uniquely registered: no other Application
* on the card will be able to register the same service name (until this
* service name is deregistered (see {@link #deregisterService})). If the
* service name identifies a family of service, no other Application on the
* card will be able to register a service of that family.<p>
*
* The OPEN shall first check that the Application invoking this method
* corresponds to <code>this</code> entry and that it has the Global Service
* Privilege.<p>
*
* Then the OPEN shall check that the specified service name:<ul>
*
* <li>is not already uniquely registered in the GlobalPlatform Registry; if
* the service name identifies an entire family of services, then the OPEN
* shall check that no service name of that family is registered.
*
* <li>was previously recorded for the Application corresponding to
* <code>this</code> entry (i.e. specified as part of System Install
* Parameters in the INSTALL command).
*
* </ul>
*
* If any of the above conditions is not satisfied, this method shall throw an
* exception (see below). Otherwise, the specified service name shall be
* uniquely registered in the GlobalPlatform Registry.<p>
*
* @param sServiceName the service name that shall be uniquely registered.<p>
*
* A service name is encoded on 2 bytes, the 1st byte identifying a family of
* services and the 2nd byte identifying a service within that family. If the
* 2nd byte is set to <code>0x00</code>, the caller of this method is
* registering an entire family of service.<p>
*
* The {@link GPSystem} class defines a set of constants
* <code>FAMILY_XXX</code> (of the <code>byte</code> type) that may be used to
* build a service name (of the <code>short</code> type) suitable to invoke
* this method as shown in the following examples:<ul>
*
* <li><code>(short)(({@link GPSystem#FAMILY_CVM}<<8)|0x11)</code>
*
* <li><code>(short)(({@link GPSystem#FAMILY_HTTP_ADMINISTRATION}<<8)|0x00)</code>
*
* </ul>
*
* @exception ISOException if this method is not supported or if the
* conditions allowing to register the service name are not satisfied.
*
* @see #deregisterService
* @see GPSystem#getService
* @see GPSystem#FAMILY_CVM
* @see GPSystem#FAMILY_SECURE_CHANNEL
* @see GPSystem#FAMILY_USSM
* @see GPSystem#FAMILY_AUTHORITY
* @see GPSystem#FAMILY_HTTP_ADMINISTRATION
* @see GPSystem#FAMILY_HTTP_REPORT
*/
public void registerService(short sServiceName) throws ISOException;
/**
* Sets the Life Cycle state of the Application corresponding to
* <code>this</code> entry.<p>
*
* This method enforces the Life Cycle State transition rules described in
* Card Specification v2.2.1 section 5.<p>
*
* If <code>this</code> entry corresponds to the Issuer Security Domain (ISD),
* then the OPEN shall check that the requested transition complies with Card
* Life Cycle State transition rules. If needed, the OPEN shall check that the
* Application invoking this method has the Card Lock Privilege or the Card
* Terminate Privilege.<p>
*
* Otherwise, the following rules shall apply:<ul>
*
* <li>If <code>this</code> entry corresponds to a Security Domain, then the
* OPEN shall check that the requested transition complies with Security
* Domains' Life Cycle State transition rules.
*
* <li>If <code>this</code> entry does not correspond to a Security Domain,
* then the OPEN shall check the requested transition complies with
* Applications' Life Cycle State transition rules.
*
* <li>If this method is invoked to transition an Application (or Security
* Domain) from the INSTALLED state to the SELECTABLE state, then the request
* shall be rejected.
*
* <li>If the high order bit (b8) of <code>bState</code> is set to 1, then the
* call to this method shall be interpreted as an attempt to lock an
* Application (or Security Domain), and other bits of <code>bState</code>
* shall be ignored (b7-b1).
*
* <li>If <code>this</code> entry corresponds to an Application (or Security
* Domain) that is currenly locked, then only the high order bit (b8) of
* <code>bState</code> shall be taken into account and, if it is set to 0 then
* the call to this method shall be interpreted as an attempt to unlock the
* Application (or Security Domain). Other bits of <code>bState</code> shall
* be ignored (b7-b1).
*
* <li>If this method is invoked to lock or unlock an Application (or Security
* Domain), then the OPEN shall check that the Application invoking this
* method either corresponds to <code>this</code> entry or has the Global Lock
* Privilege.
*
* </ul>
*
* @param bState the new Life Cycle State. See Card Specification v2.2.1
* section 11.1.1 for details on Life Cycle State Coding. A value of {@link
* GPSystem#APPLICATION_LOCKED} (resp. 0x00) may be used to request locking
* (resp. unlocking) an Application or a Security Domain (other than the ISD).
*
* @return <code>true</code> if the transition was successful,
* <code>false</code> otherwise.
*/
public boolean setState(byte bState);
}

View File

@@ -0,0 +1,507 @@
package org.globalplatform;
import javacard.framework.*;
/**
* This class exposes a subset of the behavior of the OPEN to the
* outside world. The OPEN implements and enforces a Card Issuer's security
* policy relating to these services. It provides functionality at
* the same level as the JCRE, i.e. the "system" context with special
* privileges.
* @since <ul>
* <li>export file version 1.0: initial version.
* <li>export file version 1.1: new services and/or constants added.
* <li>export file version 1.3: new services and/or constants added.
* <li>export file version 1.5: new services and/or constants added.
* <li>export file version 1.6: reviewed overall description of this interface.
* </ul>
*/
public class GPSystem
{
/**
* The current applet context is in the Life Cycle State of INSTALLED (0x03).
* <p>Note:<ul>
* <li><em>The Life Cycle State INSTALLED could be indicated along with another application
* specific Life Cycle State, e.g. a value of (0x07) indicates that the applet has been made
* selectable.</em>
* </ul>
*/
public static final byte APPLICATION_INSTALLED = (byte) 0x03;
/**
* The current applet context is in the Life Cycle State of SELECTABLE (0x07).
* <p>Note:<ul>
* <li><em>The Life Cycle State SELECTABLE could be indicated along with another application
* specific Life Cycle State.</em>
* </ul>
*/
public static final byte APPLICATION_SELECTABLE = (byte) 0x07;
/**
* The current applet context is in the Life Cycle State of LOCKED (0x80).
*
* To know whether an application is locked or not, a logical AND operation
* shall be performed between this constant and the current application life
* cycle state.
*/
public static final byte APPLICATION_LOCKED = (byte) 0x80;
/**
* The Security Domain is in the Life Cycle State of PERSONALIZED (0x0F).
*/
public static final byte SECURITY_DOMAIN_PERSONALIZED = (byte) 0x0F;
/**
* The card is in the Life Cycle State of OP_READY (0x01).
*/
public static final byte CARD_OP_READY = (byte) 0x01;
/**
* The card is in the Life Cycle State of INITIALIZED (0x07).
*/
public static final byte CARD_INITIALIZED = (byte) 0x07;
/**
* The card is in the Life Cycle State of SECURED (0x0F).
*/
public static final byte CARD_SECURED = (byte) 0x0F;
/**
* The card is in the Life Cycle State of CARD_LOCKED (0x7F).
*/
public static final byte CARD_LOCKED = (byte) 0x7F;
/**
* The card is in the Life Cycle State of TERMINATED (0xFF).
*/
public static final byte CARD_TERMINATED = (byte) 0xFF;
/**
* Indicates that the required CVM interface is a Global PIN (0x11).
*/
public static final byte CVM_GLOBAL_PIN = (byte) 0x11;
/**
* Indicates that the required CVM interface is the ETSI PIN App 1 (0x01).
* @since export file version 1.5
*/
public static final byte CVM_ETSI_PIN_APP_1 = (byte) 0x01;
/**
* Indicates that the required CVM interface is the ETSI PIN App 2 (0x02).
* @since export file version 1.5
*/
public static final byte CVM_ETSI_PIN_APP_2 = (byte) 0x02;
/**
* Indicates that the required CVM interface is the ETSI PIN App 3 (0x03).
* @since export file version 1.5
*/
public static final byte CVM_ETSI_PIN_APP_3 = (byte) 0x03;
/**
* Indicates that the required CVM interface is the ETSI PIN App 4 (0x04).
* @since export file version 1.5
*/
public static final byte CVM_ETSI_PIN_APP_4 = (byte) 0x04;
/**
* Indicates that the required CVM interface is the ETSI PIN App 5 (0x05).
* @since export file version 1.5
*/
public static final byte CVM_ETSI_PIN_APP_5 = (byte) 0x05;
/**
* Indicates that the required CVM interface is the ETSI PIN App 6 (0x06).
* @since export file version 1.5
*/
public static final byte CVM_ETSI_PIN_APP_6 = (byte) 0x06;
/**
* Indicates that the required CVM interface is the ETSI PIN App 7 (0x07).
* @since export file version 1.5
*/
public static final byte CVM_ETSI_PIN_APP_7 = (byte) 0x07;
/**
* Indicates that the required CVM interface is the ETSI PIN App 8 (0x08).
* @since export file version 1.5
*/
public static final byte CVM_ETSI_PIN_APP_8 = (byte) 0x08;
/**
* Indicates the family of the Secure Channel Global Service Identifier (0x81).
* @since export file version 1.1
*/
public static final byte FAMILY_SECURE_CHANNEL = (byte) 0x81;
/**
* Indicates the family of the CVM Global Service Identifier (0x82).
* @since export file version 1.1
*/
public static final byte FAMILY_CVM = (byte) 0x82;
/**
* @since export file version 1.2
* @deprecated Use {@link #FAMILY_AUTHORITY} instead.
*/
public static final byte FAMILY_AUHTORITY= (byte)0x83;
/**
* Indicates the family of the Authority Service Identifier (0x83).
* @since export file version 1.2
*/
public static final byte FAMILY_AUTHORITY= (byte)0x83;
/**
* Indicates the family of the HTTP Administration Service Identifier (0x84).
* @since export file version 1.3
*/
public static final byte FAMILY_HTTP_ADMINISTRATION= (byte)0x84;
/**
* Indicates the family of the HTTP Report Service Identifier (0x85).
* @since export file version 1.3
*/
public static final byte FAMILY_HTTP_REPORT= (byte)0x85;
/**
* Indicates the family of the USSM Global Service Identifier (0xA0).
* @since export file version 1.1
*/
public static final byte FAMILY_USSM = (byte) 0xA0;
/**
* Indicates the generic Global Service Identifier (0x80).
* @since export file version 1.1
*/
public static final byte GLOBAL_SERVICE_IDENTIFIER = (byte) 0x80;
/**
* Gets the Life Cycle State of the current applet context.<p>
*
* @return the Life Cycle State of the current applet context.
*
* @see #APPLICATION_INSTALLED
* @see #APPLICATION_SELECTABLE
* @see #APPLICATION_LOCKED
*/
public static byte getCardContentState()
{
return ((byte)0);
}
/**
* Gets the Life Cycle State of the card.<p>
*
* @return the Life Cycle State of the card.
*
* @see #CARD_OP_READY
* @see #CARD_INITIALIZED
* @see #CARD_SECURED
* @see #CARD_LOCKED
* @see #CARD_TERMINATED
*/
public static byte getCardState()
{
return((byte)0);
}
/**
* Gets a reference to a {@link CVM} instance provided by the OPEN.<p>
*
* Since export file version 1.1, this method allows looking up for CVM
* instances registered as Global Services by so-called Global Services
* Applications (i.e. Applications having the Global Service Privilege) and
* the following mechanism is defined to retrieve such instances:<ul>
*
* <li>The OPEN looks up in the GlobalPlatform Registry for a Global Services
* Application (i.e. having the Global Service Privilege) that registered a
* Global Service with the specified <code>bCVMIdentifier</code> identifier
* for the {@link #FAMILY_CVM} family, or that uniquely registered a Global
* Service for the entire {@link #FAMILY_CVM} family.
*
* <li>The OPEN then retrieves the corresponding {@link GlobalService}
* instance by invoking the {@link Applet#getShareableInterfaceObject} method
* of that Global Services Application with the <code>clientAID</code>
* parameter set to the AID of the current applet context (i.e. the one
* invoking this method) and the <code>parameter</code> parameter set to
* {@link #GLOBAL_SERVICE_IDENTIFIER}.
*
* <li>The OPEN then retrieves a {@link Shareable} instance by invoking the
* {@link GlobalService#getServiceInterface} method with the
* <code>clientRegistryEntry</code> parameter set to the {@link
* GPRegistryEntry} instance of the current applet context (i.e. the one
* invoking this method), with the <code>sServiceName</code> set to
* <code>({@link #FAMILY_CVM}<<8|bCVMIdentifier)</code>, the
* <code>baBuffer</code> parameter set to <code>null</code>, and the
* <code>sOffset</code> and <code>sLength</code> set to zero.
*
* <li>Finally, the OPEN casts the retrieved {@link Shareable} instance to the
* {@link CVM} interface before returning it.
*
* <li>If any of the above steps fails, the requested CVM instance is deemed
* to be unavailable.
*
* </ul>
*
* For backward compatibility, the {@link #CVM_GLOBAL_PIN} constant can still
* be used to access a Global Service registered with the <code>({@link
* #FAMILY_CVM}<<8|{@link #CVM_GLOBAL_PIN})</code> identifier, or uniquely
* registered for the entire {@link #FAMILY_CVM} family. Whether such a
* service is available or not still depends on the issuer's policy.
*
* @param bCVMIdentifier identifies the requested CVM instance.
*
* @return requested CVM instance, or <code>null</code> if the requested CVM
* instance is not available.
*
* @see #CVM_GLOBAL_PIN
*/
public static CVM getCVM(byte bCVMIdentifier)
{
return (null);
}
/**
* Gets a {@link SecureChannel} instance.<p>
*
* This method allows the Application associated with the current applet
* context to retrieve a {@link SecureChannel} instance provided by its
* associated Security Domain.<p>
*
* Since export file version 1.1, although not required, this method may be
* implemented using the Global Service facility, in which case {@link
* SecureChannel} instances would be registered by Security Domains as Global
* Services. In this case, Security Domains shall check that they only provide
* such {@link SecureChannel} instances to their associated Applications.<p>
*
* @return the SecureChannel interface object reference.
*
* @see #getCVM the GPSystem.getCVM() method for an example of how to access a Global Service.
*/
public static SecureChannel getSecureChannel()
{
return (null);
}
/**
* Locks the card.
*
* This method shall be used to transition the card to {@link #CARD_LOCKED}
* Life Cycle State.<p>
*
* The OPEN shall check that the Application invoking this method has the Card
* Lock Privilege. If not, the transition shall be rejected. <p>
*
* @return <code>true</code> if the card was locked, <code>false</code> otherwise.
*/
public static boolean lockCard()
{
return (false);
}
/**
* Terminates the card.
*
* This method shall be used to transition the card to {@link
* #CARD_TERMINATED} Life Cycle State.<p>
*
* The OPEN shall check that the Application invoking this method has the Card
* Terminate Privilege. If not, the transition shall be rejected.<p>
*
* @return <code>true</code> if the card was terminated, <code>false</code> otherwise.
*/
public static boolean terminateCard()
{
return (false);
}
/**
* Sets the historical bytes of the Answer To Reset (ATR) string.<p>
*
* This method only updates the ATR string that is used for the contact-based
* IO interface (as specified by [ISO/IEC 7816] upon power-up or cold
* reset. The ATR string used for warm reset shall remain unchanged. The new
* historical bytes shall be visible upon next power-up or cold reset.<p>
*
* The OPEN shall check that the Application invoking this method has the Card
* Reset Privilege and that the <code>bLength</code> is both positive and
* lower than 16. If not, the change shall be rejected.<p>
*
* Notes:<ul>
* <li><em>The OPEN is responsible for synchronizing the length of historical
* bytes in the format character (low order nibble of T0) of the ATR string.</em>
* </ul>
*
* @param baBuffer byte array containing the ATR historical bytes.
* @param sOffset offset of the ATR historical bytes.
* @param bLength length of the ATR historical bytes.
*
* @return <code>true</code> if ATR historical bytes were set, <code>false</code> otherwise.
*/
public static boolean setATRHistBytes (byte[] baBuffer, short sOffset, byte bLength)
{
return (false);
}
/**
* Sets the Life Cycle state of the Application invoking this method.
*
* This method allows the Application associated with the current applet
* context to lock itself or to change its state from an application specific
* Life Cycle State to another application specific Life Cycle State. An
* Application cannot unlock itself.<p>
*
* The OPEN shall check that the Application is currently in an application
* specific Life Cycle State (i.e. in the range [0x07 .. 0x7F] and with its 3
* low order bits set to 1), in particular that it is not in the {@link
* #APPLICATION_INSTALLED} state and not currently locked. If not, the change
* shall be rejected.
*
* The OPEN shall check that <code>bState</code> either encodes an application
* specific Life Cycle State or has its high order bit (b8) set to 1: the
* latter case shall be interpreted as a request from the the Application to
* lock itself.
*
* @param bState either an application specific Life Cycle State (i.e. in the
* range [0x07 .. 0x7F] and with its 3 low order bits set to 1), or any value
* having its high order bit (b8) set to 1. A value of {@link
* #APPLICATION_LOCKED} may be used to request locking the Application.
*
* @return <code>true</code> if the Life Cycle State of the Application was
* changed, <code>false</code> otherwise.
*
* @see #APPLICATION_INSTALLED
* @see #APPLICATION_LOCKED
*
* @since <ul>
* <li>export file version 1.0: initial version.
* <li>export file version 1.5: this method now allows the application
* associated with the current applet context to lock itself.
* </ul>
*/
public static boolean setCardContentState(byte bState)
{
return (false);
}
/**
* Gets a {@link GPRegistryEntry} instance.<p>
*
* This method allows the Application associated with the current applet
* context to get its own {@link GPRegistryEntry} instance or the one of
* another Application.
*
* If the <code>aid</code> parameter is not <code>null</code> and does not
* identify the Application invoking this method, the OPEN shall check that
* the Application invoking this method has the Global Registry Privilege. If
* not, this method shall return <code>null</code>.<p>
*
* @param aid the AID of the Application whose {@link GPRegistryEntry}
* instance is requested. Use <code>null</code> to retrieve the {@link
* GPRegistryEntry} instance of the current applet context.
*
* @return the requested {@link GPRegistryEntry} instance if it was found in
* the GlobalPlatform Registry and the Application invoking this method is
* allowed to access that entry, <code>null</code> otherwise.
*
* @since export file version 1.1
*/
public static GPRegistryEntry getRegistryEntry(AID aid)
{
return (null);
}
/**
* Gets a {@link GlobalService} instance matching the specified service name
* (<code>sServiceName</code>).<p>
*
* The <code>serverAID</code> parameter is optional (i.e. may be set to
* <code>null</code>) and identifies the Global Services Application providing
* the service.<p>
*
* The OPEN shall look for the Global Services Application providing the
* service:<ul>
*
* <li>If the <code>serverAID</code> parameter is <code>null</code>, then the
* OPEN shall look for the specified service name among the set of uniquely
* registered service names (see {@link GPRegistryEntry#registerService}). If
* the requested service name only identifies a family of services, then the
* OPEN shall look for a uniquely registered service name of the requested
* family (the search strategy remains implementation dependent). If a
* matching service name is found, the Global Services Application is the one
* that uniquely registered that service name.
*
* <li>Otherwise, if the <code>serverAID</code> parameter is not
* <code>null</code>, then the OPEN shall look in the GlobalPlatform Registry
* for the corresponding Application:<ul>
*
* <li>If the Application does not have the Global Service Privilege, then
* the search is deemed to be unsuccessful.
*
* <li>If the requested service name (or family of service) was not
* previously recorded for that Application (i.e. not specified as part of
* System Install Parameters in the INSTALL command), then the search is
* deemed to be unsuccessful.
*
* </ul>
*
* </ul>
*
* If a Global Services Application was found, then the OPEN shall retrieve
* the {@link GlobalService} instance by invoking the {@link
* Applet#getShareableInterfaceObject} method of that Global Services
* Application with the <code>clientAID</code> parameter set to the AID of the
* current applet context (i.e. the one invoking this method) and the
* <code>parameter</code> parameter set to {@link #GLOBAL_SERVICE_IDENTIFIER}.
*
* @param serverAID AID of the Global Services Application providing the
* requested service, or <code>null</code> if the caller of this method is
* requesting a uniquely registered service name.<p>
*
* @param sServiceName service name identifying a service or a family of
* services.<p>
*
* A service name is encoded on 2 bytes, the 1st byte identifying a family of
* services and the 2nd byte identifying a service within that family. If the
* 2nd byte is set to <code>0x00</code>, the caller of this method is
* requesting a service of the specified family, but does not care exactly
* which service within that family.<p>
*
* This class defines a set of constants <code>FAMILY_XXX</code> (of the
* <code>byte</code> type) that may be used to build a service name (of the
* <code>short</code> type) suitable to invoke this method as shown in the
* following examples:<ul>
*
* <li><code>(short)(({@link #FAMILY_CVM}<<8)|0x11)</code>
*
* <li><code>(short)(({@link #FAMILY_HTTP_ADMINISTRATION}<<8)|0x00)</code>
*
* </ul>
*
* @return the {@link GlobalService} instance giving access to the requested
* service, or <code>null</code> if the Global Services Application could not
* be found or did not provide a {@link GlobalService} instance.
*
* @see #GLOBAL_SERVICE_IDENTIFIER
* @see #FAMILY_CVM
* @see #FAMILY_SECURE_CHANNEL
* @see #FAMILY_USSM
* @see #FAMILY_AUTHORITY
* @see #FAMILY_HTTP_ADMINISTRATION
* @see #FAMILY_HTTP_REPORT
* @see GPRegistryEntry#registerService
*
* @since export file version 1.1
*/
public static GlobalService getService(AID serverAID, short sServiceName)
{
return (null);
}
}

View File

@@ -0,0 +1,258 @@
package org.globalplatform;
import javacard.framework.*;
/**
* This interface allows requesting a Global Services Application for a
* Shareable Interface Object (SIO) providing the actual service.<p>
*
* To retrieve an instance of this interface, an Application shall invoke the
* {@link GPSystem#getService} method.<p>
*
* @since export file version 1.1
*/
public interface GlobalService extends Shareable
{
/**
* Key Access indicating key may be used by the Security Domain and any
* associated Application (0x00).
*/
public static final byte KEY_ACCESS_ANY = (byte) 0x00;
/**
* Key Access indicating key may be used by the Security Domain but not by any
* associated Application (0x01).
*/
public static final byte KEY_ACCESS_SECURITY_DOMAIN = (byte) 0x01;
/**
* Key Access indicating key may be used by any associated Application but not
* by the Security Domain (0x02).
*/
public static final byte KEY_ACCESS_APPLICATION = (byte) 0x02;
/**
* Key type indicating AES (0x88).
*/
public static final byte KEY_TYPE_AES = (byte) 0x88;
/**
* Key type indicating Triple DES reserved for specific implementations (0x81).
*/
public static final byte KEY_TYPE_3DES = (byte) 0x81;
/**
* Key type indicating Triple DES in CBC mode (0x82).
*/
public static final byte KEY_TYPE_3DES_CBC = (byte) 0x82;
/**
* Key type indicating DES with ECB/CBC implicitly known (0x80).
*/
public static final byte KEY_TYPE_DES = (byte) 0x80;
/**
* Key type indicating DES in CBC mode (0x84).
*/
public static final byte KEY_TYPE_DES_CBC = (byte) 0x84;
/**
* Key type indicating DES in ECB mode (0x83).
*/
public static final byte KEY_TYPE_DES_ECB = (byte) 0x83;
/**
* Key type indicating extended key format (0xFF).
*/
public static final byte KEY_TYPE_EXTENDED = (byte) 0xFF;
/**
* Key type indicating HMAC SHA1, length of HMAC implicitly known (0x90).
*/
public static final byte KEY_TYPE_HMAC_SHA1 = (byte) 0x90;
/**
* Key type indicating HMAC SHA1, length of HMAC is 160 bits (0x91).
*/
public static final byte KEY_TYPE_HMAC_SHA1_160 = (byte) 0x91;
/**
* Key type indicating RSA Private Key Chinese Remainder p component (0xA4).
*/
public static final byte KEY_TYPE_RSA_PRIVATE_CRT_P = (byte) 0xA4;
/**
* Key type indicating RSA Private Key Chinese Remainder q component (0xA5).
*/
public static final byte KEY_TYPE_RSA_PRIVATE_CRT_Q = (byte) 0xA5;
/**
* Key type indicating RSA Private Key Chinese Remainder pq component (0xA6).
*/
public static final byte KEY_TYPE_RSA_PRIVATE_CRT_PQ = (byte) 0xA6;
/**
* Key type indicating RSA Private Key Chinese Remainder dp1 component (0xA7).
*/
public static final byte KEY_TYPE_RSA_PRIVATE_CRT_DP1 = (byte) 0xA7;
/**
* Key type indicating RSA Private Key Chinese Remainder dq1 component (0xA8).
*/
public static final byte KEY_TYPE_RSA_PRIVATE_CRT_DQ1 = (byte) 0xA8;
/**
* Key type indicating RSA Private exponent (0xA3).
*/
public static final byte KEY_TYPE_RSA_PRIVATE_EXPONENT = (byte) 0xA3;
/**
* Key type indicating RSA Private Key modulus (0xA2).
*/
public static final byte KEY_TYPE_RSA_PRIVATE_MODULUS = (byte) 0xA2;
/**
* Key type indicating RSA Public Key exponent (0xA0).
*/
public static final byte KEY_TYPE_RSA_PUBLIC_EXPONENT = (byte) 0xA0;
/**
* Key type indicating RSA Public Key modulus (0xA1).
*/
public static final byte KEY_TYPE_RSA_PUBLIC_MODULUS = (byte) 0xA1;
/**
* Key usage indicating computation and decipherment (0x40).
*/
public static final byte KEY_USAGE_COMPUTATION_DECIPHERMENT = (byte) 0x40;
/**
* Key usage indicating sensitive data confidentiality (0x08).
*/
public static final byte KEY_USAGE_CONFIDENTIALITY = (byte) 0x08;
/**
* Key usage indicating cryptographic authorization (0x01).
*/
public static final byte KEY_USAGE_CRYPTOGRAPHIC_AUTHORIZATION = (byte) 0x01;
/**
* Key usage indicating cryptographic checksum e.g. MAC (0x04).
*/
public static final byte KEY_USAGE_CRYPTOGRAPHIC_CHECKSUM = (byte) 0x04;
/**
* Key usage indicating Digital Signature (0x02).
*/
public static final byte KEY_USAGE_DIGITAL_SIGNATURE = (byte) 0x02;
/**
* Key usage indicating Secure Messaging in command data field (0x10).
*/
public static final byte KEY_USAGE_SM_COMMAND = (byte) 0x10;
/**
* Key usage indicating Secure Messaging in response data field (0x20).
*/
public static final byte KEY_USAGE_SM_RESPONSE = (byte) 0x20;
/**
* Key usage indicating verification and encipherment (0x80).
*/
public static final byte KEY_USAGE_VERIFICATION_ENCIPHERMENT = (byte) 0x80;
/**
* Gets a Shareable Interface Object (SIO) actually providing the requested service.<p>
*
* The Application invoking this method shall set the
* <code>clientRegistryEntry</code> to its own {@link GPRegistryEntry}
* instance.<p>
*
* The Global Services Application shall verify the validity of the request
* according to its own security policies for the specified
* <code>sServiceName</code>, based on the identity and characteristics of the
* Application invoking this method as registered by the specified
* <code>clientRegistryEntry</code>, and possibly based on the data contained
* in the <code>baBuffer</code> byte array.<p>
*
* If the request is valid, the Global Service Application returns a SIO
* implementing the actual service: this SIO may either be this {@link
* GlobalService} instance or another object. If the request is deemed to be
* invalid, the Global Services Application shall reject the request by either
* throwing an exception or returning <code>null</code>.<p>
*
* It is assumed that the Application invoking this method is aware of the
* interface (extension of the {@link Shareable} interface) to which the
* retrieved SIO shall be casted in order to acces the service.<p>
*
* Notes:<ul>
*
* <li><em>It shall be noticed that an Application having the Global Registry
* Privilege could potentially invoke this method with the
* <code>clientRegistryEntry</code> parameter set to the {@link
* GPRegistryEntry} instance of another Application. If the Global Services
* Application itself has the Global Registry Privilege, it may explicitly
* retrieve and check the {@link GPRegistryEntry} instance of the Application
* invoking this method, by performing the following call:
* <code>GPSystem.getRegistryEntry(JCSystem.getPreviousContextAID())</code>.</em>
*
* </ul>
*
* @param clientRegistryEntry the {@link GPRegistryEntry} instance of the
* requesting Application.<p>
* @param sServiceName a service name identifying the requested service.<p>
*
* A service name is encoded on 2 bytes, the 1st byte identifying a family of
* services and the 2nd byte identifying a service within that family.<p>
*
* The {@link GPSystem} class defines a set of constants
* <code>FAMILY_XXX</code> (of the <code>byte</code> type) that may be used to
* build a service name (of the <code>short</code> type) suitable to invoke
* this method as shown in the following examples:<ul>
*
* <li><code>(short)(({@link GPSystem#FAMILY_CVM}<<8)|0x11)</code>
*
* <li><code>(short)(({@link GPSystem#FAMILY_HTTP_ADMINISTRATION}<<8)|0x00)</code>
*
* </ul>
*
* @param baBuffer byte array containing additional parameters of the request,
* potentially authentication data. Must be <em>global</em> byte array.
* @param sOffset offset of the additional parameters.
* @param sLength length of the additional parameters.
*
* @return the SIO providing the actual service, or <code>null</code> if the
* service is not available or the request was rejected. Alternatively, this
* method may reject the request by throwing an <code>ISOException</code>.
*
* @exception ISOException if the request was rejected. Although not
* mandatory, it is recommended to use one of the following reason codes:<ul>
* <li>'6A88' if the specified service was not found or is not available.
* <li>'6982' if some security conditions are not satisfied.
* <li>'6985' if some other conditions are not satisfied.
* </ul>
* Alternatively, this method may reject the request by returning <code>null</code>.
*
* @exception SecurityException if the Global Services Application requires
* reading data from <code>baBuffer</code> and <code>baBuffer</code> is not a
* <em>global</em> byte array.
* @exception NullPointerException if the Global Services Application requires
* reading data from <code>baBuffer</code> and <code>baBuffer</code> is
* <code>null</code>.
* @exception ArrayIndexOutOfBoundsException if the Global Services
* Application requires reading data from <code>baBuffer</code> and reading
* data would cause access of data outside array bounds.
*
* @see GPSystem#getService
* @see GPSystem#FAMILY_CVM
* @see GPSystem#FAMILY_SECURE_CHANNEL
* @see GPSystem#FAMILY_USSM
* @see GPSystem#FAMILY_AUTHORITY
* @see GPSystem#FAMILY_HTTP_ADMINISTRATION
* @see GPSystem#FAMILY_HTTP_REPORT
*/
public Shareable getServiceInterface(GPRegistryEntry clientRegistryEntry, short sServiceName, byte[] baBuffer, short sOffset, short sLength) throws ISOException;
}

View File

@@ -0,0 +1,53 @@
package org.globalplatform;
import javacard.framework.*;
/**
* This interface defines a method to trigger a new HTTP administration session.<p>
*
* To retrieve an instance of this interface, an Application shall use the
* {@link GlobalService} instance, if available, registered with a service name
* of <code>({@link GPSystem#FAMILY_HTTP_ADMINISTRATION}<<8|0x00)</code>.
*
* @see GlobalService
* @see GPSystem#getService
*
* @since <ul>
* <li>export file version 1.3: initial version.
* <li>export file version 1.6: reviewed overall description of this interface.
* </ul>
*/
public interface HTTPAdministration extends Shareable
{
/**
* Triggers a new administration session. <p>
*
* The Security Domain of the Application invoking this method will handle the
* SCP81 (PSK TLS) security of the communication. <p>
*
* The Application invoking this method will be notified of the result of the
* request if it implements the {@link HTTPReportListener} interface. <p>
*
* @param triggeringParameters byte array containing administration session
* triggering parameters.
* @param offset offset of triggering parameters within <code>triggeringParameters</code>.
* @param length length of triggering parameters.
*
* @exception SecurityException if <code>triggeringParameters</code> is not
* accessible in the caller's context.
* @exception NullPointerException if <code>triggeringParameters</code> is
* <code>null</code>.
* @exception ArrayIndexOutOfBoundsException if reading triggering parameters
* command would cause access of data outside array bounds.
*
* @exception ISOException with one of the following reason codes: <ul>
* <li> <code>SW_WRONG_DATA</code> if parameters are not
* correctly formatted.
* <li> <code>SW_CONDITIONS_NOT_SATISFIED</code> if the request could not be
* processed (e.g. if no SCP81 session could be established).
* </ul>
*/
void requestHTTPAdministrationSession (byte[] triggeringParameters,
short offset,
short length);
}

View File

@@ -0,0 +1,47 @@
package org.globalplatform;
import javacard.framework.Shareable;
/**
* This interface defines a method to receive a notification upon completion
* (success or failure) of an HTTP Administration Session.<p>
*
* An Application that wishes to receive such a notification shall implement the
* {@link javacard.framework.Applet#getShareableInterfaceObject} to return an
* {@link HTTPReportListener} instance when the <code>clientAID</code> parameter
* is set to <code>null</code>, and the <code>parameter</code> parameter is set
* to {@link GPSystem#FAMILY_HTTP_REPORT}.<p>
*
* @since <ul>
* <li>export file version 1.3: initial version.
* <li>export file version 1.6: reviewed overall description of this interface.
* </ul>
*/
public interface HTTPReportListener extends Shareable
{
/**
* Constant notifying that a HTTP Administration Session ended successfully
*/
public final static short HTTP_SESSION_NO_ERROR=0x0001;
/**
* Constant notifying that a HTTP Administration Session failed. That is, the
* retry policy of the session is exhausted and the administration session
* request is aborted.
*/
public final static short HTTP_SESSION_ERROR=(short) 0x8001;
/**
* Notifies the Application that the requested HTTP Administration Session
* successfully completed or not. <p>
*
* The OPEN notifies the Application when the HTTP Administration Session ends
* or when the retry policy is exhausted.<p>
*
* @param status Either {@link #HTTP_SESSION_NO_ERROR} (failure) or {@link
* #HTTP_SESSION_ERROR} (success).
*/
public void httpAdministationSessionReport(short status);
}

View File

@@ -0,0 +1,85 @@
package org.globalplatform;
import javacard.framework.*;
/**
* This interface defines a method through which an Application may forward
* input data to another Application and retrieve output data from that
* Application.<p>
*
* This interface shall be implemented by an Application that wishes to receive
* personalization data forwarded by its associated Security Domain and request
* outputting response data. In such a scenario, if the Application implements
* both the {@link Application} and the {@link Personalization} interface, then
* the Security Domain shall use the {@link Personalization} interface. <p>
*
* @see Application
*
* @since export file version 1.2
*/
public interface Personalization extends Shareable
{
/**
* Processes application specific data received from another on-card entity.<p>
*
* If the Application invoking this method is a Security Domain then it shall
* be assumed that:<ul>
*
* <li>Both the <code>inBuffer</code> and <code>outBuffer</code> byte arrays
* are <em>global</em> byte arrays;
*
* <li>The data forwarded by the Security Domain is a STORE DATA command. The
* <code>sOffset</code> parameter locates the class byte of the command and
* the <code>sLength</code> parameter indicates the length of the entire
* command (i.e. header + data field).
*
* <li>The Security Domain will send back to the off-card entity the output
* data written by the Application to <code>outBuffer</code>.
*
* <li>Any exception thrown by this method will be rethrown by the Security
* Domain, hence will be converted to and returned as a response status word
* to the off-card entity. If the exception is an {@link ISOException}, then
* the status word will be the reason code of that exception. Otherwise, a
* status word of '6F00' will be returned.
*
* </ul>
*
* <p>Notes:<ul>
*
* <li><em>Upon invocation of this method, the Java Card VM performs a
* context switch.</em>
*
* <li><em>As the Application is not the currently selected Application, it
* should not attempt to access transient memory of type
* <code>CLEAR_ON_DESELECT</code> during the processing of this method.</em>
*
* <li><em>The Application is responsible for managing the atomic
* modification of its own data, if needed.</em>
*
* <li><em>As this method may be invoked by a Security Domain immaterial of
* the Application's internal state, the Application is responsible for
* ensuring that its internal state is valid for this operation.</em>
*
* </ul>
*
* @param inBuffer byte array containing input data. Must be a <em>global</em>
* byte array.
* @param inOffset offset of input data within <code>inBuffer</code>.
* @param inLength length of input data.
* @param outBuffer byte array where output data shall be written. Must be a
* <em>global</em> byte array.
* @param outOffset offset where output data shall be written within
* <code>inBuffer</code>.
*
* @return the number of bytes written to <code>outBuffer</code>.
*
* @exception SecurityException if <code>inBuffer</code> or
* <code>outBuffer</code> is not a <em>global</em> byte array.
* @exception NullPointerException if <code>inBuffer</code> or
* <code>outBuffer</code> is <code>null</code>.
* @exception ArrayIndexOutOfBoundsException if reading intput data or writing
* output data would cause access of data outside array bounds.
*/
public short processData (byte[] inBuffer, short inOffset, short inLength, byte[] outBuffer, short outOffset);
}

View File

@@ -0,0 +1,493 @@
package org.globalplatform;
import javacard.framework.*;
/**
* This interface defines basic Secure Channel services used to manage entity
* authentication and protect APDU commands and responses. It is typically
* exposed by a Security Domain to its associated Applications.<p>
*
* Using an instance of this interface requires no knowledge of the underlying
* protocols, algorithms and secrets used to perform entity authentication and
* provide integrity and confidentiality of APDU commands and responses, which
* only need to be known by the provider of the instance.<p>
*
* An Application that wishes to delegate such activities to its associated
* Security Domain shall retrieve a {@link SecureChannel} instance provided by
* its associated Security Domain using the {@link GPSystem#getSecureChannel}
* method. On some implementations, this {@link SecureChannel} instance may also
* be retrieved using the {@link GPSystem#getService} method.<p>
*
* If the card supports logical channels, this interface is responsible for
* correctly handling any indication of a logical channel number present in the
* class byte of APDU commands. In particular, it shall be able to verify and
* remove (i.e. unwrap) the protection (if any) of an APDU command without
* altering such indication of a logical channel number.
*
* Upon successful initialization of a Secure Channel Session, the
* implementation shall establish both a compulsory Session Security Level and a
* Current Security Level:<ul>
*
* <li>The compulsory <em>Session Security Level</em> is the Security Level negotiated
* during the initialization of the session, that shall apply as a minimum
* security requirement during the entire Secure Channel Session. The compulsory
* Session Security Level shall only be reset upon (full) termination of the
* Secure Channel Session.
*
* <li>The <em>Current Security Level</em> is the security requirement that
* shall indeed apply to APDU commands (and responses) during the session and is
* initialized to the same value as the compulsory Session Security Level at the
* beginning of the session. The Current Security Level may be subsequently
* updated (e.g. R-MAC or not) upon successful processing of some commands
* specific to the underlying security protocol or upon successful invocation of
* the {@link SecureChannelx#setSecurityLevel} method (if supported), but shall
* never get below the minimum requirement defined by the compulsory Session
* Security Level. The Current Security Level, as well as any information
* relating to the Secure Channel Session (except the compulsory Session
* Security Level), shall be reset upon abortion or termination of the Secure
* Channel Session.
*
* </ul>
*
* <a name="sc_abort">See Card Specification v2.2.1 section 10.2.3 for details
* about abortion and termination of a Secure Channel Session.</a><p>
*
* Until it is aborted, a Secure Channel Session shall be bound to the following
* information:<ul>
* <li>the Logical Channel on which it was initiated: The session only exists on
* the Logical Channel on which it was initiated. If an Application invokes this
* interface from another Logical Channel, then the interface shall behave as if
* no Secure Channel Session was currently open but the existing session shall
* neither be aborted nor be terminated. For resource management reasons,
* attempts to open another Secure Channel Session from another Logical Channel
* (i.e. concurrently to the existing one(s)) may be rejected by the
* implementation.
* <li>the Application that initiated the session: Any call performed to this
* interface by another Application from the Logical Channel attached to the
* session shall be rejected with an exception. For example, this may happen if
* this other Application somehow obtained a reference to this interface using
* the sharing mechanism.
*
* </ul>
*
* @since <ul>
* <li>export file version 1.0: initial version.
* <li>export file version 1.6: reviewed overall description of this interface.
* </ul>
*/
public interface SecureChannel extends Shareable
{
/**
* Entity Authentication has occurred as Application Provider (0x80).
* <p>Note:<ul>
* <li><em>Entity Authentication and the level of security that will be applied by the {@link #wrap}
* and {@link #unwrap} methods are not necessarily related. A Security Domain, by default, could
* verify the MAC on any command passed as a parameter in the {@link #unwrap} method without
* entity authentication previously having occurred.</em> </ul>
*/
public static final byte AUTHENTICATED = (byte) 0x80;
/**
* The {@link #unwrap} method will decrypt incoming command data (0x02).
* <p>Note:<ul>
* <li><em>Command data decryption could be indicated along with entity authentication and one or more
* levels of security.</em> </ul>
*/
public static final byte C_DECRYPTION = (byte) 0x02;
/**
* The {@link #unwrap} method will verify the MAC on an incoming command (0x01).
* <p>Note:<ul>
* <li><em>MAC verification could be indicated along with entity authentication and one or more
* levels of security, e.g. a value of '03' indicates that while entity authentication has not
* occurred, the {@link #unwrap} method will decrypt the command data of incoming commands
* and verify the MAC on incoming commands.</em> </ul>
*/
public static final byte C_MAC = (byte) 0x01;
/**
* The {@link #wrap} method will encrypt the outgoing response data (0x20).
* <p>Note:<ul>
* <li><em>Response data encryption could be indicated along with entity authentication and one
* or more levels of security.</em> </ul>
*/
public static final byte R_ENCRYPTION = (byte) 0x20;
/**
* The {@link #wrap} method will generate a MAC for the outgoing response data (0x10).
* <p>Note:<ul>
* <li><em>MAC generation could be indicated along with entity authentication and one or more
* levels of security, e.g. a value of '91' indicates that entity authentication has occurred,
* that the {@link #unwrap} method will verify the MAC on incoming commands and that the
* {@link #wrap} method will generate a MAC on outgoing response data.</em> </ul>
*/
public static final byte R_MAC = (byte) 0x10;
/**
* Entity Authentication has not occurred (0x00).
* <p>Note:<ul>
* <li><em>Entity Authentication and the level of security that will be applied by the
* {@link #wrap} and {@link #unwrap} methods are not necessarily related. A
* Security Domain, by default, could verify the MAC on any command passed as a parameter in
* the {@link #unwrap} method without entity authentication previously having occurred.</em>
* <li><em>The {@link #wrap} and {@link #unwrap} methods will not apply any cryptographic
* processing to command or response data.</em> </ul>
*/
public static final byte NO_SECURITY_LEVEL = (byte) 0x00;
/**
* Entity Any Authentication has occurred (0x40).
* <p>Note:<ul>
* <li><em>The authenticated entity is not the Application Provider of the Application.</em>
* <li><em>Entity Authentication and the level of security that will be applied by the {@link #wrap}
* and {@link #unwrap} methods are not necessarily related. A Security Domain, by default, could
* verify the MAC on any command passed as a parameter in the {@link #unwrap} method without
* entity authentication previously having occurred.</em> </ul>
*/
public static final byte ANY_AUTHENTICATED = (byte) 0x40;
/**
* Processes security related APDU commands, that is, APDU commands relating
* to the underlying security protocol.<p>
*
* As the intention is to allow an Application to use Secure Channel services
* without having any knowledge of the underlying security protocols, the
* Application may assume that APDU commands that it does not recognize are
* part of the security protocol and will be recognized by this {@link
* SecureChannel} instance. Therefore, the Application may either invoke this
* method prior to determining if it recognizes the command or only invoke
* this method for commands it does not recognize. In turn, this method will
* throw an {@link ISOException} if it does not recognize the APDU command as
* a security related APDU command.<p>
*
* This method is responsible for receiving the data field of APDU commands
* that are recognized (i.e. that belong to the security protocol). When
* processing a command, this method shall write response data in the
* <code>APDU</code> buffer at offset {@link ISO7816#OFFSET_CDATA} or return
* a status word under the form of an {@link ISOException}. The Application is
* responsible for outputting such response data and/or status word.<p>
*
* @param apdu the incoming <code>APDU</code> object.
*
* @return the number of bytes to be output (i.e. length of response data).
*
* @exception ISOException with a reason code reflecting some error detected
* by the underlying security protocol, or with one of the following reason
* codes if the APDU command is not recognized and does not relate to the
* underlying security protocol:<ul>
* <li>'6E00' if the class byte of the command is not recognized by this method.
* <li>'6D00' if the instruction byte of the command is not recognized by this method.
* </ul>
*/
public short processSecurity(APDU apdu) throws ISOException;
/**
* Computes and adds security protection to an outgoing APDU response
* according to the <em>Current Security Level</em>.<p>
*
* If the Current Security Level is {@link #NO_SECURITY_LEVEL} and is
* different from the compulsory Session Security Level (i.e. a previous
* Secure Channel Session was <a href="#sc_abort">aborted</a> but not fully
* terminated), then this method shall throw an exception (see below).<p>
*
* Otherwise, this method shall attempt computing and adding a security
* protection to the outgoing message according to the Current Security Level
* (e.g. {@link #R_MAC} and/or {@link #R_ENCRYPTION}). If the Current
* Security Level does not require any protection for APDU responses (which
* includes the case where there is no Secure Channel Session currently
* open), the outgoing response message shall remain as is in the within the
* <code>baBuffer</code> byte array and the returned length shall be set to a
* value of <code>(sLength - 2)</code>, indicating the status bytes are no
* longer present at the end of the returned data.<p>
*
* Notes:<ul>
*
* <li><em>The Application is responsible for appending the expected status bytes
* at the end of the response data prior to invoking this method in order for
* them to be protected by secure messaging. The status bytes shall be
* subsequently removed by this method.</em>
*
* </ul>
*
* @param baBuffer byte array containing response data (including the
* expected status bytes).
* @param sOffset offset of response data.
* @param sLength length of response data (including the expected status
* bytes).
*
* @return length of the reformatted (wrapped) response data, with security
* information added and status bytes removed.
*
* @exception SecurityException if <code>baBuffer</code> is not accessible in
* the caller's context e.g. <code>baBuffer</code> is not a <em>global</em>
* array nor an array belonging to the caller context.
* @exception NullPointerException if <code>baBuffer</code> is <code>null</code>.
* @exception ArrayIndexOutOfBoundsException if writing security information
* in <code>baBuffer</code> would cause access of data outside array bounds.
*/
public short wrap(byte[] baBuffer, short sOffset, short sLength) throws ISOException;
/**
* Verifies and removes the security protection of an incoming APDU command
* according to the <em>Current Security Level</em>.<p>
*
* If the Current Security Level is {@link #NO_SECURITY_LEVEL} and is
* different from the compulsory Session Security Level (i.e. a previous
* Secure Channel Session was <a href="#sc_abort">aborted</a> but not fully
* terminated), then this method shall throw an exception (see below).<p>
*
* If the class byte does not indicate secure messaging (according to ISO/IEC
* 7816-4), then this method shall not attempt to verify and remove any
* security protection: the incoming command shall remain as is within the
* <code>baBuffer</code> byte array and the returned length shall be set to
* the value of the <code>sLength</code> parameter.<p>
*
* If the class byte indicates secure messaging (according to ISO/IEC
* 7816-4), then this method shall attempt verifying and removing the
* security protection according to the Current Security Level:<ul>
*
* <li>If the Current Security Level is {@link #NO_SECURITY_LEVEL}, {@link
* #AUTHENTICATED} or {@link #ANY_AUTHENTICATED}, then this method shall not
* attempt to verify and remove any security protection, the incoming command
* will remain as is within the <code>baBuffer</code> byte array (with class
* byte indicating secure messaging) and the returned length shall be set to
* the value of the <code>sLength</code> parameter.
*
* <li>Incorrect verification and removal of the security protection shall
* result in an exception being thrown (see below) and the current Secure
* Channel Session being <a href="#sc_abort">aborted</a>: all information
* relating to the Secure Channel Session, except the compulsory Session
* Security Level, shall be reset.
*
* <li>Correct verification and removal of the security protection shall
* result in the incoming command being reformatted within the
* <code>baBuffer</code> byte array (a.k.a. unwrapped command). A reformatted
* case 1 or case 2 command shall include an Lc byte set to '00'.
*
* </ul>
*
* Notes:<ul>
*
* <li><em>The Application is implicitly responsible for receiving the data field
* of the incomping APDU command prior to invoking this method.</em>
*
* <li><em>Depending on the underlying security protocol, if R_MAC is
* indicated by the Current Security Level, R-MAC computation may be
* initiated on the reformatted command once secure messaging processing of
* the incoming command has successfully completed. If no secure messaging
* processing was required for the incoming command, R-MAC computation would
* be initiated on the unmodified incoming command, appended with a Lc byte
* of '00' in the event of a case 1 or case 2 command.</em>
*
* </ul>
*
* @param baBuffer byte array containing the incoming APDU command.
* @param sOffset offset of the incoming APDU command, i.e. offset of the
* class byte.
* @param sLength length of the incoming APDU command, i.e length of the
* entire APDU command (header + data field).
*
* @return length of the reformatted (unwrapped) APDU command, i.e length of
* the entire APDU command (header + data field).
*
* @exception ISOException with one of the following reason codes (other
* reason codes specific to the underlying security protocol may be
* returned):<ul>
*
* <li>'6985' if the Current Security Level is {@link #NO_SECURITY_LEVEL} but
* the compulsory Session Security Level is different from {@link
* #NO_SECURITY_LEVEL}, that is, a previous Secure Channel Session was <a
* href="#sc_abort">aborted</a> but not fully terminated.
*
* <li>'6982' if this method failed
* verifying or removing the security protection of the incoming APDU
* command.
*
* </ul>
*
* @exception SecurityException if <code>baBuffer</code> is not accessible in
* the caller's context e.g. <code>baBuffer</code> is not a <em>global</em> array nor
* an array belonging to the caller context.
* @exception NullPointerException if <code>baBuffer</code> is <code>null</code>.
* @exception ArrayIndexOutOfBoundsException if reading the incoming APDU
* command would cause access of data outside array bounds.
*/
public short unwrap(byte [] baBuffer, short sOffset, short sLength) throws ISOException;
/**
* Decrypts sensitive user data.<p>
*
* The decryption algorithm and cryptographic key used to decrypt data, as
* well as any padding method, are known implicitly and depend on the
* underlying security protocol.<p>
*
* If the Current Security Level is {@link #NO_SECURITY_LEVEL} or the
* necessary cryptographic keys are not available, then this method shall
* throw an exception (see below).<p>
*
* Otherwise, the data shall be decrypted and the clear text data shall
* replace the encrypted data within the <code>baBuffer</code> byte
* array. The removal of padding may cause the length of the clear text data
* to be shorter than the length of the encrypted data. Any failure in the
* decryption or padding removal process shall result in an exception being
* thrown (see below).<p>
*
* Notes:<ul>
*
* <li><em>The Application is responsible for removing application specific
* padding, if any. For example, if the underlying security protocol is SCP
* '02', then no padding method is defined and this method will not remove any
* padding.</em>
*
* <li><em>The Application is responsible for checking the integrity of the
* decrypted data. </em>
*
* </ul>
*
* @param baBuffer byte array containing the data that shall be decrypted.
* @param sOffset offset of the data that shall be decrypted.
* @param sLength length of the data that shall be decrypted.
*
* @return length of the decrypted data, with any padding removed if a padding
* method is defined for the underlying security protocol.
*
* @exception ISOException with one of the following reason codes (other
* reason codes specific to the underlying security protocol may be
* returned):<ul>
*
* <li>'6985' if there is no Secure
* Channel Session currently open.
*
* <li>'6700' if the length of the data that shall
* be decrypted is not valid (e.g. underlying algorithm requires data to be
* block-aligned and input data are not).</li>
*
* </ul>
*
* @exception SecurityException if <code>baBuffer</code> is not accessible in
* the caller's context e.g. <code>baBuffer</code> is not a <em>global</em>
* array nor an array belonging to the caller context.
* @exception NullPointerException if <code>baBuffer</code> is
* <code>null</code>.
* @exception ArrayIndexOutOfBoundsException if reading user data or writing
* decrypted data would cause access of data outside array bounds.
*/
public short decryptData(byte[] baBuffer, short sOffset, short sLength) throws ISOException;
/**
* Encrypts sensitive user data.<p>
*
* If this method is not supported by the implementation or the underlying
* protocol does not define any sensitive data encryption mechanism, it shall
* do nothing and simply throw an exception (see below).<p>
*
* The encryption algorithm and cryptographic key used to encrypt data, as
* well as any padding method, are known implicitly and depend on the
* underlying security protocol.<p>
*
* If the Current Security Level is {@link #NO_SECURITY_LEVEL} or the
* necessary cryptographic keys are not available, then this method shall
* throw an exception (see below).<p>
*
* Otherwise, the data shall be padded (NOTE: depends on the underlying
* protocol) and encrypted and the encrypted data shall replace the clear
* text data within the <code>baBuffer</code> byte array. The addition of
* padding may cause the length of the encrypted data to be longer than the
* length of the clear text data. Any failure in the padding or encryption
* process shall result in an exception being thrown (see below).<p>
*
* Notes:<ul>
*
* <li><em>The Application is responsible for adding application specific
* padding, if needed. For example, if the underlying security protocol is SCP
* '02', then no padding method is defined and this method by itself will not
* add any padding, which may lead to an exception being thrown (see below) if
* input data are not block-aligned.
*
* </ul>
*
* @param baBuffer byte array containing the data that shall be encrypted.
* @param sOffset offset of the data that shall be encrypted.
* @param sLength length of the data that shall be encrypted.
*
* @return length of the encrypted data.
*
* @exception ISOException with one of the following reason codes (other
* reason codes specific to the underlying security protocol may be
* returned):<ul>
*
* <li>'6982' if this method is not
* supported by the implementation.
*
* <li>'6985' if there is no Secure Channel Session currently open.
*
* <li>'6700' if the length of the data that shall
* be encrypted is not valid (e.g. underlying algorithm requires data to be
* block-aligned and input data are not).</li>
*
* </ul>
*
* @exception SecurityException if <code>baBuffer</code> is not accessible in
* the caller's context e.g. <code>baBuffer</code> is not a <em>global</em>
* array nor an array belonging to the caller context.
* @exception NullPointerException if <code>baBuffer</code> is
* <code>null</code>.
* @exception ArrayIndexOutOfBoundsException if reading user data or writing
* encrypted data would cause access of data outside array bounds.
*/
public short encryptData(byte[] baBuffer, short sOffset, short sLength) throws ISOException;
/**
* Terminates the current Secure Channel Session.
*
* This method resets both the compulsory <em>Session Security Level</em> and the
* <em>Current Security Level</em> to {@link #NO_SECURITY_LEVEL} and resets all
* information relating to the current Secure Channel Session (e.g. internal
* states, session keys).<p>
*
* This method shall not fail and shall simply return if no Secure
* Channel Session has been initiated.<p>
* Notes:<ul> <li><em>It is recommended that Applications using this interface
* invoke this method in the implementation of their
* <code>Applet.deselect()</code> method.</em> </ul>
*/
public void resetSecurity();
/**
* Gets the <em>Current Security Level</em>.
*
* An Application shall invoke this method to ensure that its own specific
* security requirements are enforced by this interface. It shall also take
* into account that the Current Security Level may change during the Secure
* Channel Session (e.g. R_MAC may be enabled or disabled during a C_MAC
* session).<p>
*
* Notes:<ul>
* <li><em>The Current Security Level, as returned by this method, may be
* different for an Application invoking the method and its associated
* Security Domain depending on the underlying security protocol and the
* authenticated off-card entity's Application Provider ID (e.g. it may be
* ANY_AUTHENTICATED for the application and AUTHENTICATED for its associated
* Security Domain, and vice versa).</em>
* </ul>
*
* @return The Current Security Level, which is a combination of one or more
* the following constants:<ul>
* <li>{@link #NO_SECURITY_LEVEL}
* <li>{@link #AUTHENTICATED}
* <li>{@link #ANY_AUTHENTICATED}
* <li>{@link #C_MAC}
* <li>{@link #C_DECRYPTION}
* <li>{@link #R_MAC}
* <li>{@link #R_ENCRYPTION}
* </ul>
*/
public byte getSecurityLevel();
}

View File

@@ -0,0 +1,73 @@
package org.globalplatform;
import javacard.framework.*;
/**
* This interface is an extension of the {@link SecureChannel} interface that
* defines one supplementary method to update the <em>Current Security Level</em>
* during a Secure Channel Session.<p>
*
* An Application that wishes to use the {@link SecureChannelx} interface shall
* obtain a reference to a {@link SecureChannel} instance and try to cast it to
* the {@link SecureChannelx} interface. Whether the objects returned by the
* {@link GPSystem#getSecureChannel} method also implement the {@link
* SecureChannelx} interface is implementation dependent, however, this may be
* expressed as a requirement in specific GlobalPlatform configuration
* documents.
*
* @since <ul>
* <li>export file version 1.1: initial version.
* <li>export file version 1.6: reviewed overall description of this interface.
* </ul>
*/
public interface SecureChannelx extends SecureChannel
{
/**
* Updates the <em>Current Security Level</em>.
*
* If this method is not supported by the implementation or the underlying
* protocol does not define any sensitive data encryption mechanism, it shall
* do nothing and simply throw an exception (see below).<p>
*
* The Current Security Level cannot be set below the compulsory <em>Session
* Security Level</em>, but only equal or above. It may be increased or
* decreased during a Secure Channel Session as long as it is at least equal
* to the compulsory Session Security Level.<p>
*
* If the Current Security Level is {@link #NO_SECURITY_LEVEL} or the
* cryptographic keys required by the new Current Security Level are not
* available, then this method shall throw an exception (see below).<p>
*
* The new Current Security Level shall apply for all subsequent invocations
* of {@link SecureChannel#wrap} and {@link SecureChannel#unwrap} methods,
* except when there is no current Secure Channel Session.<p>
* @param bSecurityLevel The new Current Security Level, which shall a
* combination of one or more the following constants:<ul>
* <li>{@link #NO_SECURITY_LEVEL}
* <li>{@link #AUTHENTICATED}
* <li>{@link #ANY_AUTHENTICATED}
* <li>{@link #C_MAC}
* <li>{@link #C_DECRYPTION}
* <li>{@link #R_MAC}
* <li>{@link #R_ENCRYPTION}
* </ul>
*
* @exception ISOException with one of the following reason codes (other
* reason codes specific to the underlying security protocol may be
* returned):<ul>
*
* <li>'6982' if this method is not supported by the implementation.
*
* <li>'6985' if there is no Secure Channel Session currently open or if the
* new Current Security Level does not comply with (i.e. goes below) the
* compulsory Session Security Level.
*
* </ul>
*/
public void setSecurityLevel(byte bSecurityLevel);
}

View File

@@ -0,0 +1,70 @@
package org.globalplatform;
import javacard.framework.ISOException;
/**
* This interface is an extension of the {@link SecureChannel} interface that
* defines one supplementary method overriding the {@link
* SecureChannel#processSecurity} method.<p>
*
* An Application that wishes to use the {@link SecureChannelx2} interface shall
* obtain a reference to a {@link SecureChannel} instance and try to cast it to
* the {@link SecureChannelx2} interface. Whether the objects returned by the
* {@link GPSystem#getSecureChannel} method also implement the {@link
* SecureChannelx2} interface is implementation dependent, however, this may be
* expressed as a requirement in specific GlobalPlatform configuration
* documents.
*
* @since <ul>
* <li>export file version 1.4: initial version.
* <li>export file version 1.6: reviewed overall description of this interface.
* </ul>
*/
public interface SecureChannelx2 extends SecureChannel
{
/**
* Processes security related APDU commands, that is, APDU commands relating
* to the underlying security protocol.<p>
*
* This method shall be used in the same way as the {@link
* SecureChannel#processSecurity} method, except that the incoming APDU
* command shall be read from, and any response data shall be written to the
* <code>baBuffer</code> byte array.<p>
*
* Notes:<ul>
*
* <li><em>The applet is implicitly responsible for receiving the data field
* of the incomping APDU command prior to invoking this method.</em>
*
* </ul>
*
* @param baBuffer byte array containing the incoming APDU command.
* @param sInOffset offset of the incoming APDU command, i.e. offset of the
* class byte.
* @param sInLength length of the incoming APDU command, i.e length of the
* entire APDU command (header + data field).
* @param sOutOffset offset within <code>baBuffer</code> where response data
* (if any) shall be written.
*
* @return the number of bytes to be output (i.e. length of response data).
*
* @exception ISOException with a reason code reflecting some error detected
* by the underlying security protocol, or with one of the following reason
* codes if the APDU command is not recognized and does not relate to the
* underlying security protocol:<ul>
* <li>'6E00' if the class byte of the command is not recognized
* by this method.
* <li>'6D00' if the instruction byte of the command is not
* recognized by this method.
* </ul>
*
* @exception SecurityException if <code>baBuffer</code> is not accessible in
* the caller's context e.g. <code>baBuffer</code> is not a <em>global</em> array nor
* an array belonging to the caller context.
* @exception NullPointerException if <code>baBuffer</code> is <code>null</code>.
* @exception ArrayIndexOutOfBoundsException if reading the incoming APDU
* command would cause access of data outside array bounds.
*/
public short processSecurity(byte[] baBuffer, short sInOffset, short sInLength, short sOutOffset) throws ISOException;
}

View File

@@ -0,0 +1,8 @@
/**
* Provides a framework of classes and interfaces related to core services
* defined for smart cards based on GlobalPlatform specifications.
* @version This documentation describes API elements and behaviors associated
* with version 1.6 of this package export file.
*/
package org.globalplatform;

View File

@@ -0,0 +1,25 @@
@echo off
REM
REM Copyright 2005 Sun Microsystems, Inc. All rights reserved.
REM Use is subject to license terms.
REM
if "%OS%" == "Windows_NT" setlocal
if not "%JAVA_HOME%" == "" goto check_tool
echo Please set the JAVA_HOME environment variable.
goto end
:check_tool
if not "%JC_HOME%" == "" goto doit
echo Please set the JC_HOME environment variable.
goto end
:doit
set _CLASSES=%JC_HOME%\lib\apduio.jar;%JC_HOME%\lib\apdutool.jar;%JC_HOME%\lib\jcwde.jar;%JC_HOME%\lib\converter.jar;%JC_HOME%\lib\scriptgen.jar;%JC_HOME%\lib\offcardverifier.jar;%JC_HOME%\lib\api.jar;%JC_HOME%\lib\installer.jar;%JC_HOME%\lib\capdump.jar;%JC_HOME%\samples\classes;%CLASSPATH%;
"%JAVA_HOME%\bin\java" -classpath %_CLASSES% com.sun.javacard.apdutool.Main %*
goto end
:end
if "%OS%" == "Windows_NT" endlocal

View File

@@ -0,0 +1,25 @@
@echo off
REM
REM Copyright 2005 Sun Microsystems, Inc. All rights reserved.
REM Use is subject to license terms.
REM
if "%OS%" == "Windows_NT" setlocal
if not "%JAVA_HOME%" == "" goto check_tool
echo Please set the JAVA_HOME environment variable.
goto end
:check_tool
if not "%JC_HOME%" == "" goto doit
echo Please set the JC_HOME environment variable.
goto end
:doit
set _CLASSES=%JC_HOME%\lib\apduio.jar;%JC_HOME%\lib\apdutool.jar;%JC_HOME%\lib\jcwde.jar;%JC_HOME%\lib\converter.jar;%JC_HOME%\lib\scriptgen.jar;%JC_HOME%\lib\offcardverifier.jar;%JC_HOME%\lib\api.jar;%JC_HOME%\lib\installer.jar;%JC_HOME%\lib\capdump.jar;%JC_HOME%\samples\classes;%CLASSPATH%;
%JAVA_HOME%\bin\java -classpath %_CLASSES% com.sun.javacard.capdump.CapDump %*
goto end
:end
if "%OS%" == "Windows_NT" endlocal

View File

@@ -0,0 +1,25 @@
@echo off
REM
REM Copyright 2005 Sun Microsystems, Inc. All rights reserved.
REM Use is subject to license terms.
REM
if "%OS%" == "Windows_NT" setlocal
if not "%JAVA_HOME%" == "" goto check_tool
echo Please set the JAVA_HOME environment variable.
goto end
:check_tool
if not "%JC_HOME%" == "" goto doit
echo Please set the JC_HOME environment variable.
goto end
:doit
set _CLASSES=%JC_HOME%\lib\apduio.jar;%JC_HOME%\lib\apdutool.jar;%JC_HOME%\lib\jcwde.jar;%JC_HOME%\lib\converter.jar;%JC_HOME%\lib\scriptgen.jar;%JC_HOME%\lib\offcardverifier.jar;%JC_HOME%\lib\api.jar;%JC_HOME%\lib\installer.jar;%JC_HOME%\lib\capdump.jar;%JC_HOME%\samples\classes;%CLASSPATH%;
%JAVA_HOME%\bin\java -classpath %_CLASSES% com.sun.javacard.jcasm.cap.Main %*
goto end
:end
if "%OS%" == "Windows_NT" endlocal

View File

@@ -0,0 +1,25 @@
@echo off
REM
REM Copyright 2005 Sun Microsystems, Inc. All rights reserved.
REM Use is subject to license terms.
REM
if "%OS%" == "Windows_NT" setlocal
if not "%JAVA_HOME%" == "" goto check_tool
echo Please set the JAVA_HOME environment variable.
goto end
:check_tool
if not "%JC_HOME%" == "" goto doit
echo Please set the JC_HOME environment variable.
goto end
:doit
set _CLASSES=%JC_HOME%\lib\apduio.jar;%JC_HOME%\lib\apdutool.jar;%JC_HOME%\lib\jcwde.jar;%JC_HOME%\lib\converter.jar;%JC_HOME%\lib\scriptgen.jar;%JC_HOME%\lib\offcardverifier.jar;%JC_HOME%\lib\api.jar;%JC_HOME%\lib\installer.jar;%JC_HOME%\lib\capdump.jar;%JC_HOME%\samples\classes;%CLASSPATH%;
%JAVA_HOME%\bin\java -classpath %_CLASSES% com.sun.javacard.converter.Converter %*
goto end
:end
if "%OS%" == "Windows_NT" endlocal

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,25 @@
@echo off
REM
REM Copyright 2005 Sun Microsystems, Inc. All rights reserved.
REM Use is subject to license terms.
REM
if "%OS%" == "Windows_NT" setlocal
if not "%JAVA_HOME%" == "" goto check_tool
echo Please set the JAVA_HOME environment variable.
goto end
:check_tool
if not "%JC_HOME%" == "" goto doit
echo Please set the JC_HOME environment variable.
goto end
:doit
set _CLASSES=%JC_HOME%\lib\apduio.jar;%JC_HOME%\lib\apdutool.jar;%JC_HOME%\lib\jcwde.jar;%JC_HOME%\lib\converter.jar;%JC_HOME%\lib\scriptgen.jar;%JC_HOME%\lib\offcardverifier.jar;%JC_HOME%\lib\api.jar;%JC_HOME%\lib\installer.jar;%JC_HOME%\lib\capdump.jar;%JC_HOME%\samples\classes;%CLASSPATH%;
%JAVA_HOME%\bin\java -classpath %_CLASSES% com.sun.javacard.converter.Exp2Text %*
goto end
:end
if "%OS%" == "Windows_NT" endlocal

View File

@@ -0,0 +1,25 @@
@echo off
REM
REM Copyright 2005 Sun Microsystems, Inc. All rights reserved.
REM Use is subject to license terms.
REM
if "%OS%" == "Windows_NT" setlocal
if not "%JAVA_HOME%" == "" goto check_tool
echo Please set the JAVA_HOME environment variable.
goto end
:check_tool
if not "%JC_HOME%" == "" goto doit
echo Please set the JC_HOME environment variable.
goto end
:doit
set _CLASSES=%JC_HOME%\lib\apduio.jar;%JC_HOME%\lib\apdutool.jar;%JC_HOME%\lib\jcwde.jar;%JC_HOME%\lib\converter.jar;%JC_HOME%\lib\scriptgen.jar;%JC_HOME%\lib\offcardverifier.jar;%JC_HOME%\lib\api.jar;%JC_HOME%\lib\installer.jar;%JC_HOME%\lib\capdump.jar;%JC_HOME%\samples\classes;%CLASSPATH%;
%JAVA_HOME%\bin\java -classpath %_CLASSES% com.sun.javacard.jcwde.Main %*
goto end
:end
if "%OS%" == "Windows_NT" endlocal

Binary file not shown.

View File

@@ -0,0 +1,25 @@
@echo off
REM
REM Copyright 2005 Sun Microsystems, Inc. All rights reserved.
REM Use is subject to license terms.
REM
if "%OS%" == "Windows_NT" setlocal
if not "%JAVA_HOME%" == "" goto check_tool
echo Please set the JAVA_HOME environment variable.
goto end
:check_tool
if not "%JC_HOME%" == "" goto doit
echo Please set the JC_HOME environment variable.
goto end
:doit
set _CLASSES=%JC_HOME%\lib\apduio.jar;%JC_HOME%\lib\apdutool.jar;%JC_HOME%\lib\jcwde.jar;%JC_HOME%\lib\converter.jar;%JC_HOME%\lib\scriptgen.jar;%JC_HOME%\lib\offcardverifier.jar;%JC_HOME%\lib\api.jar;%JC_HOME%\lib\installer.jar;%JC_HOME%\lib\capdump.jar;%JC_HOME%\samples\classes;%CLASSPATH%;
"%JAVA_HOME%"\bin\java -classpath %_CLASSES% com.sun.javacard.scriptgen.Main %*
goto end
:end
if "%OS%" == "Windows_NT" endlocal

View File

@@ -0,0 +1,25 @@
@echo off
REM
REM Copyright 2005 Sun Microsystems, Inc. All rights reserved.
REM Use is subject to license terms.
REM
if "%OS%" == "Windows_NT" setlocal
if not "%JAVA_HOME%" == "" goto check_tool
echo Please set the JAVA_HOME environment variable.
goto end
:check_tool
if not "%JC_HOME%" == "" goto doit
echo Please set the JC_HOME environment variable.
goto end
:doit
set _CLASSES=%JC_HOME%\lib\apduio.jar;%JC_HOME%\lib\apdutool.jar;%JC_HOME%\lib\jcwde.jar;%JC_HOME%\lib\converter.jar;%JC_HOME%\lib\scriptgen.jar;%JC_HOME%\lib\offcardverifier.jar;%JC_HOME%\lib\api.jar;%JC_HOME%\lib\installer.jar;%JC_HOME%\lib\capdump.jar;%JC_HOME%\samples\classes;%CLASSPATH%;
%JAVA_HOME%\bin\java -classpath %_CLASSES% com.sun.javacard.offcardverifier.Verifier %*
goto end
:end
if "%OS%" == "Windows_NT" endlocal

View File

@@ -0,0 +1,25 @@
@echo off
REM
REM Copyright 2005 Sun Microsystems, Inc. All rights reserved.
REM Use is subject to license terms.
REM
if "%OS%" == "Windows_NT" setlocal
if not "%JAVA_HOME%" == "" goto check_tool
echo Please set the JAVA_HOME environment variable.
goto end
:check_tool
if not "%JC_HOME%" == "" goto doit
echo Please set the JC_HOME environment variable.
goto end
:doit
set _CLASSES=%JC_HOME%\lib\apduio.jar;%JC_HOME%\lib\apdutool.jar;%JC_HOME%\lib\jcwde.jar;%JC_HOME%\lib\converter.jar;%JC_HOME%\lib\scriptgen.jar;%JC_HOME%\lib\offcardverifier.jar;%JC_HOME%\lib\api.jar;%JC_HOME%\lib\installer.jar;%JC_HOME%\lib\capdump.jar;%JC_HOME%\samples\classes;%CLASSPATH%;
%JAVA_HOME%\bin\java -classpath %_CLASSES% com.sun.javacard.offcardverifier.VerifyExp %*
goto end
:end
if "%OS%" == "Windows_NT" endlocal

View File

@@ -0,0 +1,25 @@
@echo off
REM
REM Copyright 2005 Sun Microsystems, Inc. All rights reserved.
REM Use is subject to license terms.
REM
if "%OS%" == "Windows_NT" setlocal
if not "%JAVA_HOME%" == "" goto check_tool
echo Please set the JAVA_HOME environment variable.
goto end
:check_tool
if not "%JC_HOME%" == "" goto doit
echo Please set the JC_HOME environment variable.
goto end
:doit
set _CLASSES=%JC_HOME%\lib\apduio.jar;%JC_HOME%\lib\apdutool.jar;%JC_HOME%\lib\jcwde.jar;%JC_HOME%\lib\converter.jar;%JC_HOME%\lib\scriptgen.jar;%JC_HOME%\lib\offcardverifier.jar;%JC_HOME%\lib\api.jar;%JC_HOME%\lib\installer.jar;%JC_HOME%\lib\capdump.jar;%JC_HOME%\samples\classes;%CLASSPATH%;
%JAVA_HOME%\bin\java -classpath %_CLASSES% com.sun.javacard.offcardverifier.VerifyRev %*
goto end
:end
if "%OS%" == "Windows_NT" endlocal

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More