How to change applet's privilege and the card Historical Bytes? - javacard

I already thought that changing Historical bytes is limited to Pre-Personalization step. But, I found a method named setATRHistBytes in the GlobalPlatform APIs today.
This is its description(GlobalPlatform 2.2 Page 172) :
setATRHistBytes
public static boolean setATRHistBytes(byte[] baBuffer, short sOffset, bytebLength)
For contact cards according to ISO/IEC 7816-4 and Type A contactless cards according to ISO/IEC 14443-3, this method sets the historical bytes. The sequence of bytes will be visible on a subsequent power-up or reset.
Notes:
• The OPEN locates the entry of the current applet context in the GlobalPlatform Registry and verifies that the Application has the Card Reset privilege for the current card I/O interface;
• The OPEN is responsible for synchronizing the length of historical bytes in Format Character T0 of the ATR.
Parameters:
baBuffer - the source byte array containing the historical bytes. Must be a global array.
sOffset - offset of the historical bytes within the source byte array.
bLength - the number of historical bytes.
Returns:
true if historical bytes set, false if the Application does not have the required privilege
Now I want to change the Historical Bytes of my card. So I wrote the below program and convert it to its cap file successfully :
... /imports
public class HistoricalBytesChanger extends Applet {
public static byte[] state = { (byte) 0, (byte) 0 };
public static byte[] HistByteArray = { (byte) 0x01, (byte) 0x02,
(byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07,
(byte) 0x08, (byte) 0x09, (byte) 0x0a };
public static void install(byte[] bArray, short bOffset, byte bLength) {
new HistoricalBytesChanger().register(bArray, (short) (bOffset + 1), bArray[bOffset]);
}
public void process(APDU apdu) {
if (selectingApplet()) {
return;
}
byte[] buf = apdu.getBuffer();
switch (buf[ISO7816.OFFSET_INS]) {
case (byte) 0x00:
GPSystem.setATRHistBytes(HistByteArray, (short) 0, (byte) 10);
HistByteArray[0] = (byte) (HistByteArray[0] + 1);
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
}
As you see above it is written in way that assign 0102030405060708090A to Historical Bytes on reception of any APDU command with INS=0X00.
The problem is I don't have any idea how to set Card Reset privilege to this applet. I know that I must specify the privilege in the installation step, but I don't know how! Normally I upload my applets using GlobalPlatformPro tool. In the parameters that it support I couldn't see any related parameter :
E:\GP> gp -h
Option Description
------ -----------
-V, --version Show information about the program
-a, --apdu Send raw APDU (hex)
--all Work with multiple readers
--applet <AID> Applet AID
--cap <File> Use a CAP file as source
--create <AID> Create new instance of an applet
-d, --debug Show PC/SC and APDU trace
--default Indicate Default Selected privilege
--delete [AID] Delete something
--deletedeps Also delete dependencies
--dump <File> Dump APDU communication to <File>
--emv Use EMV diversification
--enc <GPKeySet$GPKey> Specify ENC key
-h, --help Shows this help string
-i, --info Show information
--install [File] Install applet(s) from CAP
--instance <AID> Instance AID
--kek <GPKeySet$GPKey> Specify KEK key
--key <GPKeySet$GPKey> Specify master key
--keyid <Integer> Specify key ID
--keyver <Integer> Specify key version
-l, --list List the contents of the card
--load <File> Load a CAP file
--lock <GPKeySet> Set new key
--lock-applet <AID> Lock specified applet
--mac <GPKeySet$GPKey> Specify MAC key
--make-default <AID> Make AID the default
--mode <GlobalPlatform$APDUMode> APDU mode to use (mac/enc/clr)
--new-keyver <Integer> key version for the new key
--nofix Do not try to fix PCSC/Java/OS issues
--package <AID> Package AID
--params Installation parameters
-r, --reader Use specific reader
--reinstall Remove card content during installation
--relax Relaxed error checking
--replay <File> Replay APDU responses from <File>
-s, --secure-apdu Send raw APDU (hex) via SCP
--scp <Integer> Force the use of SCP0X
--sdaid <AID> ISD AID
--sdomain Indicate Security Domain privilege
--terminate Indicate Card Lock+Terminate privilege
--uninstall <File> Uninstall applet/package
--unlock Set default key
--unlock-applet <AID> Lock specified applet
-v, --verbose Be verbose about operations
--virgin Card has virgin keys
--visa2 Use VISA2 diversification
E:\GP>
Note that I installed the applet normally, but while it return 0x9000 in reception of that command, it can't change Historical Bytes and I need to set the Card Reset privilege to my applet :
OpenSC: osc -a
Using reader with a card: ACS CCID USB Reader 0
3b:68:00:00:00:73:c8:40:12:00:90:00
OpenSC: osc -s 00A4040006010203040101 -s 00000000
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 06 01 02 03 04 01 01
Received (SW1=0x90, SW2=0x00)
Sending: 00 00 00 00
Received (SW1=0x90, SW2=0x00)
OpenSC: osc -a
Using reader with a card: ACS CCID USB Reader 0
3b:68:00:00:00:73:c8:40:12:00:90:00
OpenSC:
Questions:
1- How can I change/set the privilege of my applet?
2- Why the card return 0x9000 on reception of 0x00 0x00 x00 0x00? (I expect it to return an exception, because it is mentioned in description of setATRHistBytes that this method returns false in cases that applet privilege is not Card Reset)

The reset privilege was known before as the default selected privilege. This means you can just use the --default switch for your card - the same bit it flipped in the INSTALL for INSTALL privilege bytes if you do that.
Sometimes a card expects a cold reset (i.e. removing the card from the field or terminal) before the change in ATR bytes is communicated. This can also be a reader problem - not all readers perform a reset when reconnected, or they may cache the ATR bytes.

To set card reset privilege to an applet you need to set bit3 of first privilege byte in Install and make selectable command of the applet. If the applet is only being installed and not made selectable with the same INSTALL command the Card Reset privilege cannot be set
Actually if the card is GP201/GP211 compliance then we refer Card Reset privilege as Default Selected privilege.
If Default Selected privilege is set in GP201/GP211 compliance card then it provides two functionalities to the applet as:
The applet can modify the historical bytes
The applet will be default selected applet on basic logical channel after cold reset.
If Card Reset privilege is set in GP22 or above version of compliance card then it provides following functionalities to the applet as:
The applet can modify the historical bytes
The applet can be implicit selectability on basic logical channel if it has not been awarded to another Application by setting implicit selectable parameters to tat applet.

Related

Invalid Params issue when doing hciconfig hci0 reset

This issue I am observing with kernel above 5.0.
And with controllers that have extended advertising enabled.
I have currently tested with bluez-5.50.
The issue is something to do with "MGMT_ADV_FLAG_SEC_MASK" flag is what I could get from the code. But when and how will this flag be modified is what I dont understand.
Config: kernel 5.4.24(issue seen with any 5.0+ kernel) , bluez 5.50
I am doing following steps:
1. hciattach the BLE extended ADV enabled controller.
2. hciconfig hci0 reset.
I am getting following error for Extended Scan rsp command (during the hciconfig hci0 reset sequence):
LE Set Extended Scan Response Data (0x08|0x0038) ncmd 1
Status: Invalid HCI Command Parameters (0x12)
And this I am getting because of below written in core_v5.2:
"If the advertising set is non-scannable and the Host uses this command other than to discard existing data, the Controller shall return the error code Invalid HCI Command Parameters (0x12). If the advertising set uses scannable legacy advertising PDUs and either Operation is not 0x03 or the Scan_Response_Data_Length parameter exceeds 31 octets, the Controller shall return the error code Invalid HCI Command Parameters (0x12). If Operation is not 0x03 and Scan_Response_Data_Length is zero, the Controller shall return the error code Invalid HCI Command Parameters (0x12) "
So in my extended HCI Command Extended Advertising set command just before extended scan rsp set:
*LE Set Extended Advertising Parameters (0x08|0x0036) plen 25
Handle: 0x00
Properties: 0x0010
Use legacy advertising PDUs: ADV_NONCONN_IND
This legacy advertising is set because of the MGMT_ADV_FLAG_SEC_MASK as checked in kernel code.
I want to know which parameter from the controller LE features or anything else is required to set it right.
In my bluetooth controller multi ADV is not supported , extended ADV is supported.
Got the issue, it was with extended adv for kernel 5.4.24. In the kernel version 5.7.7.
I found this difference in file hci_request.c, function get_adv_instance_scan_rsp_len, currently(kernel 5.4.24) the code is:
static u8 get_adv_instance_scan_rsp_len(struct hci_dev *hdev, u8 instance)
{
struct adv_info *adv_instance;
/* Ignore instance 0 */
if (instance == 0x00)
return 0;
In the 5.7.7 it is changed to:
static u8 get_adv_instance_scan_rsp_len(struct hci_dev *hdev, u8 instance)
{
struct adv_info *adv_instance;
/* Instance 0x00 always set local name */
if (instance == 0x00)
return 1;
What this should change is, it should satisfy the condition below, which currently wasn’t. So basically should set the scannable flag by which the scan rsp data cmd doesnt fail:
} else if (get_adv_instance_scan_rsp_len(hdev, instance)) {
if (secondary_adv)
cp.evt_properties = cpu_to_le16(LE_EXT_ADV_SCAN_IND);
else
cp.evt_properties = cpu_to_le16(LE_LEGACY_ADV_SCAN_IND);

Reset OpenCryptoki SW Token

I build open cryptoki library from source and try to initialize the software token.
but when running pkcsconf -I -c 3 for initializing the token, I get the following Error message:
Enter the SO PIN:
Enter a unique token label: poef
Error initializing token: 0xA4 (CKR_PIN_LOCKED)
The token Info looks like this:
$ pkcsconf -t
Token #3 Info:
Label: IBM OS PKCS#11
Manufacturer: IBM Corp.
Model: IBM SoftTok
Serial Number: 123
Flags: 0xD80045 (RNG|LOGIN_REQUIRED|CLOCK_ON_TOKEN|USER_PIN_TO_BE_CHANGED|SO_PIN_COUNT_LOW|SO_PIN_LOCKED|SO_PIN_TO_BE_CHANGED)
Sessions: 0/18446744073709551614
R/W Sessions: 18446744073709551615/18446744073709551614
PIN Length: 4-8
Public Memory: 0xFFFFFFFFFFFFFFFF/0xFFFFFFFFFFFFFFFF
Private Memory: 0xFFFFFFFFFFFFFFFF/0xFFFFFFFFFFFFFFFF
Hardware Version: 1.0
Firmware Version: 1.0
Time: 08:07:03
So as I understand I should reset the Software Token, to get a default SO PIN and could initialize the token, to use it. But I cannot find anything about that in the official docs.
To reset everything, you have to delete the content of /var/opencryptoki/swtok
Have you seen this page https://www.ibm.com/support/knowledgecenter/en/linuxonibm/com.ibm.linux.z.lxce/lxce_initializing_ep11token.html
I have no familiarity with this specific SW P11 implementation but the command sequence here seems to make sense.
The default pin is 12345678, you would want to change that, initialize the user pin, change that. Theory being that in that sequence you wont be locked.

Why java SIM card secure channel returns "do not match"?

I'm trying to install an applet on a SIM card wich supports java card V3.0.4. When I try to establish a secure channel to load the applet, the card returns an error:
mode_211
enable_trace
establish_context
card_connect
select -AID A000000151000000
Command --> 00A4040008A000000151000000
Wrapped command --> 00A4040008A000000151000000
Response <-- 6F108408A000000151000000A5049F6501FF9000
open_sc -security 1 -keyind 0 -keyver 0 -mac_key 79AA24D80FF0056101F1D9AB6DCAF0E6
-enc_key 79AA24D80FF0056101F1D9AB6DCAF0E6
Command --> 80CA006600
Wrapped command --> 80CA006600
Response <-- 664A734806072A864886FC6B01600B06092A864886FC6B020202630906072A86488
6FC6B03640B06092A864886FC6B048000640B06092A864886FC6B040255640B06092A864886FC6B0
481079000
Command --> 8050000008F05E65BF5254BC9F00
Wrapped command --> 8050000008F05E65BF5254BC9F00
Response <-- 00005147A5190C5352322002001C1F47B6C76BABFD305EBBC2CD1BB39000
mutual_authentication() returns 0x8030F00A (The Secure Channel Protocol passed and reported do not match.)
I'm using GPShell-1.4.4. I guess the problem is using wrong key set! Am I true or there is something else I cannot guess what?!
Thanks for your response,
(I am partly reusing an answer I wrote for your previous question which you suddenly deleted)
Error code GP211_ERROR_INCONSISTENT_SCP means that GPShell's intended SCP version mismatches with the real SCP version given by the card (see here).
Check the 12th byte of card response to INITIALIZE UPDATE -- Secure Channel Protocol identifier (see e.g. GP Card Specification 2.3, section E5.1.6) and use parameter -scp.
Alternatively you might want to use GlobalPlatformPro as GPShell is quite outdated...
Beware that you can block your card by issuing multiple INITIALIZE UPDATE commands without successful authentication!
As your current question contains the complete log it is possible to parse the Card Data tag giving (according to GP 2.2.1):
66 Card Data
73 Card Recognition Data / Discretionary Data Objects
06 OID
2A864886FC6B01 {globalPlatform 1} // Card Recognition Data
60 Application Tag 0
06 OID
2A864886FC6B020202 {globalPlatform 2 2 2} // GP 2.2 Card
63 Application Tag 3
06 OID
2A864886FC6B03 {globalPlatform 3} // Card Identification Scheme
64 Application Tag 4
06 OID
2A864886FC6B048000 {globalPlatform 4 128 0x00} // SCP80 i=0x00
64 Application Tag 4
06 OID
2A864886FC6B040255 {globalPlatform 4 2 0x55} // SCP02 i=0x55
64 Application Tag 4
06 OID
2A864886FC6B048107 {globalPlatform 4 129 0x07} // SCP81 i=0x07
So you might want to use -scp 2 -scpimpl 0x55 or -scp 2 -scpimpl 85 (which happens to be the same).
Or use GlobalPlatformPro.
Alternatively -scpimpl 0x15 should work as well as the Well-known pseudo-random algorithm
(card challenge) bit in 'i' should not matter...
Good luck!

SensorTag, detect pressed buttons using gatttool

I would like to detect if a botton is pushed on my SensorTag using the gatttool, but I'm not able to do that.
In http://processors.wiki.ti.com/index.php/SensorTag_User_Guide TI reports that in order to read the pressed buttons, you should:
1) Enable test mode by writing the value 0x80 to the AA62 (CONFIGURATION) attribute.
I did that with the command:
[CON][BC:6A:29:AE:CD:E5][LE]> char-write-req 0x67 80
[CON][BC:6A:29:AE:CD:E5][LE]> Characteristic value was written successfully
Now I should be in test mode, and:
2) Enable Simple keys notification
Looking at the http://processors.wiki.ti.com/index.php/File:BLE_SensorTag_GATT_Server.pdf
and at the bluepy lib it seems I've to write 0100 in 0x60 for doing that. But
[CON][BC:6A:29:AE:CD:E5][LE]> char-write-req 0x60 0100
[CON][BC:6A:29:AE:CD:E5][LE]> Characteristic Write Request failed: Attribute can't be written
I observed that 0x61 is writtable and accept the value 0100, but I'm still not able to
detect if a key is pressed.
Any suggestion?
That PDF document may be out of date... I just tried using gatttool on my SensorTag and got button notifications with the following command: char-write-req 0x6c 0100
I'd stick with just the TI wiki for the SensorTag as it's probably more likely to be kept up-to-date. The wiki says you only need to do that "test mode" step if you want to get notifications when the side button is pressed (because normally it just activates the advertising).
Also, you probably have to figure out what handle to use on your specific device as every firmware will cause the handles to move around. What shouldn't change between firmwares is the UUID. Try the primary and characteristics commands in gatttool to get the details of the services on the device.
My primary showed this:
attr handle: 0x005e, end grp handle: 0x0068 uuid: f000aa50-0451-4000-b000-000000000000
attr handle: 0x0069, end grp handle: 0x006d uuid: 0000ffe0-0000-1000-8000-00805f9b34fb
attr handle: 0x006e, end grp handle: 0x0074 uuid: f000aa60-0451-4000-b000-000000000000
ffe0 is the UUID of the simple key service (though the wiki says it's f000ffe0, it's not on mine). So, all the handles you want to look at are from 0x69 to 0x6d
char-read-uuid 0x2902 0x69 0x6d will show all CCC (Client Characteristic Configuration) in that range:
handle: 0x006c value: 01 00
Setting that handle to 0100 will turn on notifications for that service.

Verify SHA1withECDSA signature on javacard

i have self-signed certificate signed by SHA1withECDSA algorithm using BouncyCastle.
Under BC i can verify it easily, but when i`m doing it on JavaCard it send me false everytime(Curve secp192r1 from NIST). Certificate hold sign in plain (non X9.62 mean just r+s without any TAGs).
There is my code to verify it (with values putted as constant - for tests of course).
byte[] certdata = {...}
Signature signature = Signature.getInstance(Signature.ALG_ECDSA_SHA, false);
ECPublicKey ecpk = (ECPublicKey) KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PUBLIC, KeyBuilder.LENGTH_EC_FP_192, true);
ecpk.setA(new byte[]{...}, (short)0, (short)0x0018);
ecpk.setB(new byte[]{...}, (short)0, (short)0x0018);
ecpk.setG(new byte[]{...}, (short)0, (short)0x0031);
//Point format: uncompressed tag(0x04), x, y
ecpk.setK((short)0x0001);
ecpk.setR(new byte[]{}, (short)0, (short)0x0018);
ecpk.setW(new byte[]{}, (short)0, (short)0x31);
ecpk.setFieldFP(new byte[]{}, (short)0, (short)0x0018);
signature.init(ecpk, Signature.MODE_VERIFY);
boolean result = signature.verify(certdata, (short)0, (short)certdata.length, signtab, (short)0, (short)signtab.length);
if(result) ISOException.throwIt((short)0x0001);
else ISOException.throwIt((short)0x0002);
}
'...' instead of bytes for clear view (192bits curve can do big mess).
Certificate with TAGS explanation on pastebin:
http://pastebin.com/gvqYzm2g
Thanks for any help
sevar
edit:
New tests:
All tests re on same data (PublicKey, PrivateKey, Message to be signed)
sign is randomized so i ll use 2 sign (signT - sign generated by Terminal (BC), signC - sign generated by Chip)
signT cant be verified on CHIP but can be verified on Terminal.
signC is verified on CHIP & Terminal
so I checked cross between API
Cross Relation directed to BC works well
Cross Relation directed to CHIP isn't work
pair of key generated well because when i put PrivateKey and PublicKey generated by BC to CHIP, then signature generated on the CHIP can be verified by CHIP.
KeyPair generated well
I have no idea what i should check now. Problem probably can be with filling array in ECDSA step e = SHA1(Message). Whats happen with array after hash(hash is shorter than curve and card needs to declare size of array before copy)
Signing and verification of ECDSAwithSHA-1 with Prime192v1 from Bouncy Castle to JavaCard works fine for me.
Your problem is probably format of the signature itself.
Signature is a DER encoded structure, it is a sequence (tag 0x30) of two integers (tag 0x02). In JavaCard, 56 bytes are always expected: two coordinates of length 25 plus 6 bytes of DER headers. JavaCard always expects leading zeros in each coordinate. However, BC often produces signatures without leading zeros in coordinates, so the signature can be shorter than 56 bytes and that is why JavaCard is confused.
The opposite direction is always OK, because BC can handle leading zeros, although it does not add them when creating signature.
What you should do: wrap the BC signing mechanism with your own code and ALWAYS add leading zeros to coordinates in your BC signature. If you do so, you will be able to verify the signature both in BC and JavaCard.
I would like to post my code, but unfortunately it is a part of a commercial security project...
I had a problem with verifinge a ECDSA singature (generated on JavaCard 192r1) using BouncyCastle and i found a solution. I hope that it will be useful
Verify javacard signature ALG_ECDSA_SHA on bouncy castle

Resources