Error in accessing skb (skb->data) - linux-device-driver

I'm trying to allocate a sk_buff in my code and then access its skb->data area.
I get a NULL pointer deference.
OpenWRT: Barrier Breaker
Code:
struct sk_buff *skb = NULL;
skb = __dev_alloc_skb(2400,GFP_ATOMIC);
if (skb) {
printk("head= %p \n data= %p \n tail= %p\n end= %p\n len= %d\n", skb->head,skb->data,skb->tail,skb->end,skb->len);
memset(skb->data,0,2400);
}
Dump:
I get the following stack trace:
[ 61.200000] head = ce1dca00
[ 61.200000] data = 00000b20
[ 61.210000] tail = ce1dd360
[ 61.210000] end = ce1dc9c0
[ 61.210000] len = 0
[ 61.210000] Unable to handle kernel NULL pointer dereference at virtual address 00000b20
[ 61.220000] pgd = ce240000
[ 61.220000] [00000b20] *pgd=2e554831, *pte=00000000, *ppte=00000000
[ 61.230000] Internal error: Oops: 817 [#1] SMP ARM
[ 61.230000] Modules linked in: eng qcserial pppoe ppp_async option iptable_nat usb_wwan sierra_net sierra qmi_wwan pppox ppp_generic pl2303 nf_nat_ipv4 nf_conntrack_ipv4 mac80211 ipt_MASQUERADE ftdi_sio ebtable_nat ebtable_filter ebtable_broute cfg80211 cdc_ether ath3k asix xt_time xt_tcpudp xt_tcpmss xt_string xt_statistic xt_state xt_recent xt_nat xt_multiport xt_mark xt_mac xt_limit xt_length xt_id xt_hl xt_helper xt_ecn xt_dscp xt_conntrack xt_connmark xt_connlimit xt_connbytes xt_comment xt_TCPMSS xt_REDIRECT xt_NETMAP xt_LOG xt_HL xt_DSCP xt_CT xt_CLASSIFY usbserial usbnet usbhid ums_usbat ums_sddr55 ums_sddr09 ums_karma ums_jumpshot ums_isd200 ums_freecom ums_datafab ums_cypress ums_alauda ts_kmp ts_fsm ts_bm slhc rfcomm nf_nat_irc nf_nat_ftp nf_nat nf_defrag_ipv4 nf_conntrack_irc nf_conntrack_ftp iptable_raw iptable_mangle iptable_filter ipt_REJECT ipt_ECN ip_tables hso hidp hid_generic hci_uart gsc_input ebtables ebt_vlan ebt_stp ebt_snat ebt_redirect ebt_pkttype ebt_mark_m ebt_mark ebt_limit ebt_ip6 ebt_ip ebt_dnat ebt_arpreply ebt_arp ebt_among ebt_802_3 e1000e crc_ccitt compat cdc_wdm cdc_acm btusb bnep bluetooth act_connmark act_skbedit act_mirred em_u32 cls_u32 cls_tcindex cls_flow cls_route cls_fw sch_hfsc sch_ingress configs hid evdev ledtrig_usbdev xt_LED ledtrig_netdev ledtrig_morse ledtrig_heartbeat ledtrig_gpio batman_adv libcrc32c ip6t_REJECT ip6table_raw ip6table_mangle ip6table_filter ip6_tables x_tables nf_conntrack_ipv6 nf_conntrack nf_defrag_ipv6 nfsd nfsv3 nfs bonding ip_gre gre e1000 ifb ip_tunnel tun snd_compress snd_pcm_oss snd_mixer_oss snd_pcm snd_page_alloc snd_timer snd_rawmidi snd_seq_device snd_hwdep snd soundcore vfat fat ntfs lockd sunrpc nls_iso8859_1 nls_cp437 regmap_spi regmap_i2c regmap_core lzo_decompress lzo_compress rfkill input_core ipv6 arc4 crypto_blkcipher usb_storage uhci_hcd gpio_button_hotplug ext4 crc16 jbd2 mbcache exportfs ptp crc32c crypto_hash [last unloaded: iwlwifi]
[ 61.230000] CPU: 0 PID: 1850 Comm: hostapd Not tainted 3.10.49 #1
[ 61.230000] task: cf97ac60 ti: ce1d6000 task.ti: ce1d6000
[ 61.230000] PC is at __memzero+0x24/0x80
[ 61.230000] LR is at 0x0
[ 61.230000] pc : [<c000c1a4>] lr : [<00000000>] psr: 20000013
[ 61.230000] sp : ce1d7d04 ip : 00000000 fp : ce1d7d2c
[ 61.230000] r10: 00008914 r9 : 00000001 r8 : ce44d400
[ 61.230000] r7 : 00004000 r6 : ce44d400 r5 : 00000008 r4 : ce094560
[ 61.230000] r3 : 00000000 r2 : 00000000 r1 : 000008e0 r0 : 00000b20
[ 61.230000] Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
[ 61.230000] Control: 00c5787d Table: 2e24000a DAC: 00000015
I have tried using alloc_skb, dev_alloc_skb also.
ath5k uses __dev_alloc_skb() and successfully uses the returned skb->data on the target platform.
Also the value of skb->data (data = 00000b20) seems to be relative. Is it relative to the skb->head.
Please help.
Thanks

You don't need to use private methods (starting with __), use alloc_skb or dev_alloc_skb (for device drivers, it will be freed automatically) instead.
Also, it is always better to use the provided API for the instance of the sk_buff structure rather than accessing the private fields. See the existing usages for examples: http://lxr.free-electrons.com/ident?i=dev_alloc_skb

Related

Use GPIO as chip select for SPI ACPI overlay

I want to use a GPIO pin as a new chip select for SPI on an Up Squared board. The Up squared uses an Intel Pentium N4200, so it's a x86 machine. I have managed to this on a Raspberry Pi by using Device Tree Overlays but as this is an x86 machine I may have to use ACPI overlays.
The Up squared has two spi available and they propose here to use ACPI overlays, this repo, which actually works very well. Below one of the asl files they use
/*
* This ASL can be used to declare a spidev device on SPI0 CS0
*/
DefinitionBlock ("", "SSDT", 5, "INTEL", "SPIDEV0", 1)
{
External (_SB_.PCI0.SPI1, DeviceObj)
Scope (\_SB.PCI0.SPI1)
{
Device (TP0) {
Name (_HID, "SPT0001")
Name (_DDN, "SPI test device connected to CS0")
Name (_CRS, ResourceTemplate () {
SpiSerialBus (
0, // Chip select
PolarityLow, // Chip select is active low
FourWireMode, // Full duplex
8, // Bits per word is 8 (byte)
ControllerInitiated, // Don't care
1000000, // 10 MHz
ClockPolarityLow, // SPI mode 0
ClockPhaseFirst, // SPI mode 0
"\\_SB.PCI0.SPI1", // SPI host controller
0 // Must be 0
)
})
}
}
}
I compiled this file using
$ sudo iasl spidev1.0.asl > /dev/null
$ sudo mv spidev1.0.asl /lib/firmware/acpi-upgrades
$ sudo update-initramfs -u -k all
Then I reboot an I can see a device and communicate through it.
up#up:~$ ls /dev/spi*
/dev/spidev1.0
Thus, I decided to write my own overlay based on themeta-acpi samples from intel and I wrote this:
/*
* This ASL can be used to declare a spidev device on SPI0 CS2
*/
DefinitionBlock ("", "SSDT", 5, "INTEL", "SPIDEV2", 1)
{
External (_SB_.PCI0.SPI1, DeviceObj)
External (_SB_.PCI0.GIP0.GPO, DeviceObj)
Scope (\_SB.PCI0.SPI1)
{
Name (_CRS, ResourceTemplate () {
GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionOutputOnly,
"\\_SB.PCI0.GIP0.GPO", 0) {
22 // pin 22 is BCM25 or 402 in linux
}
})
Name (_DSD, Package() {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () { "compatible", "spidev" }, // not sure if this is needed
Package () {
"cs-gpios", Package () {
0,
0,
^SPI1, 0, 0, 0, // index 0 in _CRS -> pin 22
}
},
}
})
Device (TP2) {
Name (_HID, "SPT0001")
Name (_DDN, "SPI test device connected to CS2")
Name (_CRS, ResourceTemplate () {
SpiSerialBus (
2, // Chip select
PolarityLow, // Chip select is active low
FourWireMode, // Full duplex
8, // Bits per word is 8 (byte)
ControllerInitiated, // Don't care
1000000, // 10 MHz
ClockPolarityLow, // SPI mode 0
ClockPhaseFirst, // SPI mode 0
"\\_SB.PCI0.SPI1", // SPI host controller
0 // Must be 0
)
})
}
}
}
But I cannot see the new device. What am I missing?
Edit:
I have modified the code with a code which actually worked. I can see now a device on /dev/spidev1.2.
However, the CS on pin 22 is low all the time which shouldn't be the case. is the number of the pin correct? I'm using pin numbering from here
Edit 2:
Here is the output of my kernel version
Linux up 5.4.65-rt38+ #1 SMP PREEMPT_RT Mon Feb 28 13:42:31 CET 2022 x86_64 x86_64 x86_64 GNU/Linux
I compiled this up linux repository with the RT patch for the right kernel version.
I also installed the upboard-extras package and I'm actually able to communicate through spi for devices /dev/spidev1.0 and /dev/spidev1.1. So I think I have configured the up squared correctly.
There is nongpio file under /sys/class/gpio
up#up:~/aru$ ls /sys/class/gpio
export gpiochip0 gpiochip267 gpiochip310 gpiochip357 gpiochip434 unexport
I can set the GPIO to 1 or 0 and I can see the output on a multimeter, so I think I have right permissions for GPIO.
Edit 3:
Please find in this link the .dat result from acpidump -o up2-tables.dat
I assume that you are using this board. To be able to use I/O pins(i2c, spi etc.), you need to enable them firstly. Easy way to check you already enabled them or not is that typing in terminal:
uname -a
Output of this will be look like:
Linux upxtreme-UP-WHL01 5.4.0-1-generic #2~upboard2-Ubuntu SMP Thu Jul 25 13:35:27 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
In here #2~upboard2-Ubuntu part can be changed accordingto your board type. However if you don't see a similar result, then you didn't configure your board yet. Otherway to check it, go to folder: /sys/class/gpio and check the ngpio file. Inside it, there should be written 28.
To use any I/O pins(i2c, spi etc.), you don't need to change anything on BIOS side, because its coming to you defaultly enabled.
Please check the up-wiki page, and update your board kernel after linux installation. Then your I/O configurations will be enabled. Up-wiki main page.

Maxim MAX14830 in Linux x86 / ACPI

I am receiving a fatal error when attempting to load the Maxim MAX14830 SPI-to-QuadUART chip in a CentOS8 (x86_64) environment. The SPI controller in use is the Intel E3900 Atom, from which I am able to successfully mount and interact with using SPIDEV.
After reviewing several examples from the ARM world, I believe the issue lies in that I am not passing the "clocks" parameter to the max310x driver, but I have been unable to find a suitable example for describing a "phandle to the IC source clock" in ACPI.
The chip's clock input (Pin 45, XIN) is driven by a standard clock oscillator running at 7.3728 MHz.
DefinitionBlock ("e3900-spi.aml", "SSDT", 5, "INTEL", "SPIDEV", 1)
{
External (_SB_.PCI0.SPI1, DeviceObj)
Scope (\_SB.PCI0.SPI1)
{
Device (MAX1) {
Name (_HID, "PRP0001")
Name (_DDN, "Maxim MAX14380 Quad UART")
Name (_CRS, ResourceTemplate () {
SpiSerialBus (
0, // Chip select
PolarityLow, // Chip select is active low
FourWireMode, // Full duplex
8, // Bits per word is 8 (byte)
ControllerInitiated, // slave mode
1000000, // 1 MHz
ClockPolarityLow, // SPI mode 0
ClockPhaseFirst, // SPI mode 0
"\\_SB.PCI0.SPI1", // SPI host controller
0, // Must be 0
ResourceConsumer // Slave device
)
})
Name (_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () {"compatible", "maxim,max14830"},
Package () {"clock-names", "osc"},
Package () {"clock-frequency", 7372800},
Package () {"reg", 0},
}
})
}
Device (TP11) {
Name (_HID, "SPT0001")
Name (_DDN, "E3900-SPI1-CS1")
Name (_CRS, ResourceTemplate () {
SpiSerialBus (
1, // Chip select
PolarityLow, // Chip select is active low
FourWireMode, // Full duplex
8, // Bits per word is 8 (byte)
ControllerInitiated, // Don't care
1000000, // 1 MHz
ClockPolarityLow, // SPI mode 0
ClockPhaseFirst, // SPI mode 0
"\\_SB.PCI0.SPI1", // SPI host controller
0 // Must be 0
)
})
}
}
}
The relevant output from dmesg is:
[ 1.974203] max310x spi-PRP0001:03: Cannot get clock
[ 1.975951] max310x: probe of spi-PRP0001:03 failed with error -22
The datasheet for the part can be found here: https://datasheets.maximintegrated.com/en/ds/MAX14830.pdf
Any guidance or relevant example link would be appreciated. Thanks!
EDIT: I found an example for how to reference another object at https://www.kernel.org/doc/html/latest/firmware-guide/acpi/dsd/leds.html; the following AML complied correctly, but resulted in a kernel panic. This discussion (https://lore.kernel.org/lkml/914341e7-ca94-054d-6127-522b745006b4#arm.com/T/) leads me to believe that use of the common clock framework is not supported in ACPI, so any drivers that make use of it cannot be used with a ACPI + _DSD configuration.
DefinitionBlock ("e3900-spi.aml", "SSDT", 5, "INTEL", "SPIDEV", 1)
{
External (_SB_.PCI0.SPI1, DeviceObj)
Scope (\_SB.PCI0.SPI1)
{
Device (CLK1) {
Name (_HID, "PRP0001")
Name (_DDN, "Maxim Clock Object")
Name (_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () {"compatible", "fixed-clock"},
Package () {"clock-cells", 0},
Package () {"clock-frequency", 7372800},
}
})
}
Device (MAX1) {
Name (_HID, "PRP0001")
Name (_DDN, "Maxim MAX14380 Quad UART")
Name (_CRS, ResourceTemplate () {
SpiSerialBus (
0, // Chip select
PolarityLow, // Chip select is active low
FourWireMode, // Full duplex
8, // Bits per word is 8 (byte)
ControllerInitiated, // slave mode
100000, // 100 kHz
ClockPolarityLow, // SPI mode 0
ClockPhaseFirst, // SPI mode 0
"\\_SB.PCI0.SPI1", // SPI host controller
0, // Must be 0
ResourceConsumer // Slave device
)
})
Name (_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () {"compatible", "maxim,max14830"},
Package () {"clock-names", "osc"},
Package () {"clocks", ^CLK1},
Package () {"reg", 0},
}
})
}
Device (TP11) {
Name (_HID, "SPT0001")
Name (_DDN, "E3900-SPI1-CS1")
Name (_CRS, ResourceTemplate () {
SpiSerialBus (
1, // Chip select
PolarityLow, // Chip select is active low
FourWireMode, // Full duplex
8, // Bits per word is 8 (byte)
ControllerInitiated, // Don't care
1000000, // 1 MHz
ClockPolarityLow, // SPI mode 0
ClockPhaseFirst, // SPI mode 0
"\\_SB.PCI0.SPI1", // SPI host controller
0 // Must be 0
)
})
}
}
}
With the driver updates provided by 0andriy (https://lore.kernel.org/linux-serial/20201007084635.594991-1-andy.shevchenko#gmail.com/T/#u), I was able to get the /dev/ttyMAX devices to appear, although I needed to perform further modifications to force oscillator clocking; the driver was still dropping to the "Cannot get clock" error.
I modeled my AML after this example (https://github.com/westeri/meta-acpi/blob/master/recipes-bsp/acpi-tables/samples/edison/sc16is7xx.asl), which resulted in the following:
DefinitionBlock ("e3900-spi.aml", "SSDT", 5, "INTEL", "SPI", 1)
{
External (_SB_.PCI0.XHC_.RHUB.HS06.GPIO, DeviceObj)
External (_SB_.PCI0.SPI1, DeviceObj)
Scope (\_SB.PCI0.SPI1)
{
Device (MAX1) {
Name (_HID, "PRP0001")
Name (_DDN, "Maxim MAX14380 Quad UART")
Name (_CRS, ResourceTemplate () {
SpiSerialBus (
0, // Chip select
PolarityLow, // Chip select is active low
FourWireMode, // Full duplex
8, // Bits per word is 8 (byte)
ControllerInitiated, // slave mode
1000000, // 1 MHz
ClockPolarityLow, // SPI mode 0
ClockPhaseFirst, // SPI mode 0
"\\_SB.PCI0.SPI1", // SPI host controller
0, // Must be 0
ResourceConsumer // Slave device
)
GpioInt (Level, ActiveLow, Exclusive, PullDefault, 0x0000,
"\\_SB.PCI0.XHC.RHUB.HS06.GPIO", 0x00, ResourceConsumer, , ) { 18 }
})
Name (_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () {"compatible", "maxim,max14830"},
Package () {"clock-frequency", 7372800},
}
})
}
}
}
However, the driver was still failing in the devm_request_threaded_irq function:
[ 15.951778] max310x spi-PRP0001:00: MAX14830 ID: 0xb4
[ 15.965699] max310x spi-PRP0001:00: Reference clock set to 7372800 Hz
[ 15.968883] spi-PRP0001:00: ttyMAX0 at I/O 0x0 (irq = -517, base_baud = 460800) is a MAX14830
[ 15.972907] spi-PRP0001:00: ttyMAX1 at I/O 0x20 (irq = -517, base_baud = 460800) is a MAX14830
[ 15.985941] spi-PRP0001:00: ttyMAX2 at I/O 0x40 (irq = -517, base_baud = 460800) is a MAX14830
[ 15.990046] spi-PRP0001:00: ttyMAX3 at I/O 0x60 (irq = -517, base_baud = 460800) is a MAX14830
[ 16.009260] max310x spi-PRP0001:00: Unable to reguest IRQ -517
[ 16.021810] max310x: probe of spi-PRP0001:00 failed with error -22
Being a novice at C code, I wasn't able to find a way to correct the issue and ended up just commenting it out so that the mounts were not automatically torn down.
At this point, I am able to successfully query them with the setserial utility and access the devices with minicom.
[root#hwtest ~]# setserial -g /dev/ttyMAX*
/dev/ttyMAX0, UART: undefined, Port: 0x0000, IRQ: -517, Flags: low_latency
/dev/ttyMAX1, UART: undefined, Port: 0x0020, IRQ: -517, Flags: low_latency
/dev/ttyMAX2, UART: undefined, Port: 0x0040, IRQ: -517, Flags: low_latency
/dev/ttyMAX3, UART: undefined, Port: 0x0060, IRQ: -517, Flags: low_latency
I am handing the PCB back to the EE to verify the serial ports are actually working (it does not have easy test points exposed), and I will update this answer if it doesn't.
EDIT: We are able to send data while configured in this manner, but the receive path is not working, likely due to the IRQ issue. I will retest with a 5.11 kernel and report back. The current status is with LTS kernel version 5.4.70, with manual patching of the max310x driver.

SwiftySandboxFileAccess UserDefaults value

SwiftySandboxFileAccess works the first time the user approves the NSOpenPanel selection, but the next time the app opens, the security bookmark doesn't have access even though SwiftySandboxFileAccess thinks it has access just because a value is saved in the UserDefaults I think?
This is what SwiftySandboxFileAccess is saving in UserDefaults
"bd_file:///Volumes/": <626f6f6b fc010000 00000410 30000000 75703e99 3136c5a3 905214f4 1d55afdf
f9680acc 65a5c354 86b39a29 ee2e1683 1c010000 04000000 03030000 00080028 07000000 01010000
566f6c75 6d657300 04000000 01060000 10000000 08000000 04030000 93d14501 00000000 04000000
01060000 2c000000 08000000 00040000 41c188f9 52800000 18000000 01020000 02000000 00000000
0f000000 00000000 00000000 00000000 08000000 01090000 66696c65 3a2f2f2f 0c000000 01010000
4d616369 6e746f73 68204844 08000000 04030000 0050065e 3a000000 08000000 00040000 41c1ab00
f8865976 24000000 01010000 35384630 35383433 2d414237 332d3442 34342d42 3344372d 34374434
39373543 46434536 18000000 01020000 81000000 01000000 ef130000 01000000 00000000 00000000
01000000 01010000 2f000000 00000000 01050000 a8000000 feffffff 01000000 00000000 0d000000
04100000 20000000 00000000 05100000 3c000000 00000000 10100000 58000000 00000000 40100000
48000000 00000000 02200000 08010000 00000000 05200000 78000000 00000000 10200000 88000000
00000000 11200000 bc000000 00000000 12200000 9c000000 00000000 13200000 ac000000 00000000
20200000 e8000000 00000000 30200000 14010000 00000000 10d00000 04000000 00000000>
What's the bd_ it added at the beginning of the file:// path?
What're all these 8 bit things?
More Context:
This is how I'm trying to use the security bookmark:
func accessRunFileVacuum(args: VacuumCli) {
let access = SandboxFileAccess()
let success = access.access(
fileURL: URL(fileURLWithPath: "/Volumes"),
askIfNecessary: true,
persistPermission: true, with: {
print("access the URL here")
self.runFileVacuumCLI(args)
})
print("🤩 pickFile success: \(success)")
}
"access the URL here" ..., URL... hum... 🤔
from:
https://github.com/ConfusedVorlon/SwiftySandboxFileAccess/blob/master/SwiftySandboxFileAccessDemo/SwiftySandboxDemo/Manager.swift#L42
I was reading a related security bookmarks ticket and it mentioned that the Security Bookmark needs to be saved as a URL and then passed into the sub-process that wants to use it:
https://stackoverflow.com/a/27321020/1762493
the with: {} block is wrapped in startAccessingSecurityScopedResource/stopAccessingSecurityScopedResource already via SwiftySandboxFileAccess seen here: https://github.com/ConfusedVorlon/SwiftySandboxFileAccess/blob/master/SwiftySandboxFileAccess/Classes/SandboxFileAccess.swift#L87
runFileVacuumCLI() runs as a Queue Operation:
func runFileVacuumCLI(_ args: VacuumCli) {
checkVolumesAccess()
if queue.operationCount < 1 {
fvOperation = FileVacuumOperation(vacuumCli: args)
queue.addOperations([fvOperation], waitUntilFinished: false)
}
}
SandboxFileAccess().requestPermissions() allowed control when startAccessingSecurityScopedResource was invoked. Turns out somehow calling securityScopedFileURL?.startAccessingSecurityScopedResource() == true once before trying to access the file did the trick.
To be clear, SandboxFileAccess().access() also calls startAccessingSecurityScopedResource(), then executes a passed block{}, then calls stopAccessingSecurityScopedResource(). Since my function is async, stop was getting called and my access was closed on that file.
let success = access.requestPermissions(
forFileURL: URL(fileURLWithPath: bodyString),
askIfNecessary: true,
persistPermission: true, with: { securityScopedFileURL, bookmarkData in
if (securityScopedFileURL?.startAccessingSecurityScopedResource() == true) {
self.testLog("🎲 gainAccess inside startAccessingSecurityScopedResource() == true")
}
})
self.testLog("🤩 pickFile success: \(success)")
I believe this is related to the "balancing of startAccessingSecurityScopedResource" mentioned in this other answer:
https://stackoverflow.com/a/24301326/1762493

How to write down the gpio-expander to the kernel device tree?

I use a GPIO expander (TCA6424) with i.mx8qm. The expander is connected with the processor through I²C. I wrote it down to the *.dts file:
&i2c4 {
pinctrl-0 = <&pinctrl_i2c4>;
status = "okay";
tca6424#22 {
compatible = "ti, tca6424";
reg = <0x22>;
gpio-controller;
#gpio-cells = <2>;
};
};
But the driver outputed the errors:
[ 0.816053] pca953x 8-0020: 8-0020 supply vcc not found, using dummy regulator
[ 0.823139] pca953x 8-0020: failed reading register
[ 0.827936] pca953x: probe of 8-0020 failed with error -5
Do I understand correctly 0x22 is address of device here? But where I should write down the number of I²C bus? What else could I forget to point out?

Loading applets to a real Java Card

I am trying to develop Java Card applications. I am using the newest Eclipse 4.4.2, the Java Card SDK 2.2.2, and the Eclipse Java Card Development Environment (EclipseJCDE). Previously I succeeded with the JCWDE Java Card Emulator and the APDU Tool. I was using a very basic applet that I had found in this tutorial (youtube: Tutorial 1 Java Card Master SID ENSET 20 01 14) and it was working flawlessly. What I would like to do is deploy this applet to a real Java Card (brand new Gemalto IDCore 3010), but I haven't managed so far.
I have found also this clever and straightforward tutorial (youtube:Developing on Java Card JCOP Hardware Tutorial w/ Python) about deploying applets on real cards, but it just doesn't work for me. After creating a very basic applet it uses a so called Global Platform Pro command line interface - very handy indeed - to load and manage the applets. Sadly I fail right after the first command, which would dump the ATR of the smartcard (gp -i command). This is the error message that I get after re-running the command with -d -v -i switches:
C:\JavaCard\GP>gp -d -v -i
# Detected readers from SunPCSC
[*] OMNIKEY AG Smart Card Reader USB 0
SCardConnect("OMNIKEY AG Smart Card Reader USB 0", T=*) -> T=0, 3B7D960000803180
65B0831111AC83009000
SCardBeginTransaction("OMNIKEY AG Smart Card Reader USB 0")
Reader: OMNIKEY AG Smart Card Reader USB 0
ATR: 3B7D96000080318065B0831111AC83009000
More information about your card:
http://smartcard-atr.appspot.com/parse?ATR=3B7D96000080318065B0831111AC83009
000
A>> T=0 (4+0000) 00A40400 00
A<< (0027+2) (646ms) 6F198408A000000018434D00A50D9F6E061291518101009F6501FF 9000
Auto-detected ISD AID: A000000018434D00
***** Card info:
A>> T=0 (4+0000) 80CA9F7F 00
A<< (0045+2) (12ms) 9F7F2A40705072129151810100927100004DCDC6C0033201190333011903
340119000000610000000000000000 9000
Card CPLC:
ICFabricator: 4070
ICType: 5072
OperatingSystemID: 1291
OperatingSystemReleaseDate: 5181
OperatingSystemReleaseLevel: 0100
ICFabricationDate: 9271
ICSerialNumber: 00004DCD
ICBatchIdentifier: C6C0
ICModuleFabricator: 0332
ICModulePackagingDate: 0119
ICCManufacturer: 0333
ICEmbeddingDate: 0119
ICPrePersonalizer: 0334
ICPrePersonalizationEquipmentDate: 0119
ICPrePersonalizationEquipmentID: 00000061
ICPersonalizer: 0000
ICPersonalizationDate: 0000
ICPersonalizationEquipmentID: 00000000
***** CARD DATA
A>> T=0 (4+0000) 80CA0066 00
A<< (0000+2) (5ms) 6A88
NO CARD DATA
***** KEY INFO
A>> T=0 (4+0000) 80CA00E0 00
A<< (0020+2) (11ms) E012C00401FF8110C00402FF8110C00403FF8110 9000
SCardEndTransaction()
SCardDisconnect("OMNIKEY AG Smart Card Reader USB 0", false)
Exception in thread "main" java.lang.RuntimeException: pro.javacard.gp.GPKeySet$
GPKey currently only support DES and AES keys
at pro.javacard.gp.GPKeySet$GPKey.<init>(GPKeySet.java:80)
at pro.javacard.gp.GPData.get_key_template_list(GPData.java:145)
at pro.javacard.gp.GlobalPlatform.getKeyInfoTemplate(GlobalPlatform.java
:268)
at pro.javacard.gp.GPData.print_card_info(GPData.java:260)
at pro.javacard.gp.GPTool.main(GPTool.java:339)
The other command that would list what is on the card returns an even worse error message:
pro.javacard.gp.GPException: STRICT WARNING: Card cryptogram invalid!
Card: 6B7F3BA2EF7DFC99
Host: 0FCFF9EDF25027BA
!!! DO NOT RE-TRY THE SAME COMMAND/KEYS OR YOU MAY BRICK YOUR CARD !!!
at pro.javacard.gp.GlobalPlatform.printStrictWarning(GlobalPlatform.java
:184)
at pro.javacard.gp.GlobalPlatform.openSecureChannel(GlobalPlatform.java:
513)
at pro.javacard.gp.GPTool.main(GPTool.java:371)
Since this Global Platform Pro was not working, I tried working with the less manageable standard Global Platform Interface (sourceforge: GPShell), but without any luck. Even when I tried to run their sample scripts that were given originally, I got the same error message. Having run the GPShell.exe list.txt for example (that would list the applets on the card), I got the output that the application to be selected could not be found, which I don't understand.
I copy the source code here just in case, but that shouldn't be the problem as it worked with the emulator:
package jctest;
import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
public class JCTest extends Applet {
private byte counter = 0;
private final static byte CLS = (byte) 0xB0;
private final static byte INC = (byte) 0x00;
private final static byte DEC = (byte) 0x01;
private final static byte GET = (byte) 0x02;
private final static byte INIT = (byte) 0x03;
private JCTest() {
}
public static void install(byte bArray[], short bOffset, byte bLength) throws ISOException {
new JCTest().register();
}
public void process(APDU apdu) throws ISOException {
if (this.selectingApplet())
return;
byte[] buffer = apdu.getBuffer();
if (buffer[ISO7816.OFFSET_CLA] != CLS)
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
switch (buffer[ISO7816.OFFSET_INS]) {
case INC:
++counter;
break;
case DEC:
--counter;
break;
case GET:
buffer[0] = counter;
apdu.setOutgoingAndSend((short) 0, (short) 1);
break;
case INIT:
apdu.setIncomingAndReceive();
counter = buffer[ISO7816.OFFSET_CDATA];
break;
}
}
}
After many days of trying I am sort of desperate that I can't make my brand new Java Cards work. When I insert the card into the reader, the computer only recognizes that, but not the card itself since it doesn't find a driver (I also couldn't find one, but I think that it is not essential to make things work). The task is supposed to be very simple, I just want to use an already working applet on a real Java Card. What is wrong? What am I missing?
After having finally run the gp -i command successfully, this is what I get as the output for the command: gp -visa2 -key 47454D5850524553534F53414D504C45 -unlock -virgin -d -v
C:\JavaCard\GP>gp -visa2 -key 47454D5850524553534F53414D504C45 -unlock -virgin -
d -v
# Detected readers from SunPCSC
[*] OMNIKEY CardMan 3x21 0
SCardConnect("OMNIKEY CardMan 3x21 0", T=*) -> T=0, 3B7D96000080318065B0831111AC
83009000
SCardBeginTransaction("OMNIKEY CardMan 3x21 0")
Reader: OMNIKEY CardMan 3x21 0
ATR: 3B7D96000080318065B0831111AC83009000
More information about your card:
http://smartcard-atr.appspot.com/parse?ATR=3B7D96000080318065B0831111AC83009
000
A>> T=0 (4+0000) 00A40400 00
A<< (0027+2) (645ms) 6F198408A000000018434D00A50D9F6E061291518101009F6501FF 9000
Auto-detected ISD AID: A000000018434D00
A>> T=0 (4+0008) 80500000 08 0681B19093C4A93B 00
A<< (0028+2) (72ms) 4D00927100004DD4C6C0FF01E87D06549F536080A8D1AB091B6BBE07 900
0
Host challenge: 0681B19093C4A93B
Card challenge: E87D06549F536080
Card reports SCP01 with version 255 keys
Master keys:
Version 0
ENC: Ver:0 ID:0 Type:DES3 Len:16 Value:47454D5850524553534F53414D504C45
MAC: Ver:0 ID:0 Type:DES3 Len:16 Value:47454D5850524553534F53414D504C45
KEK: Ver:0 ID:0 Type:DES3 Len:16 Value:47454D5850524553534F53414D504C45
Diversififed master keys:
Version 0
ENC: Ver:0 ID:0 Type:DES3 Len:16 Value:5B9387DE5E618B12760EBE6037B077AC
MAC: Ver:0 ID:0 Type:DES3 Len:16 Value:5454366589B6AE522F58EE7072C101DF
KEK: Ver:0 ID:0 Type:DES3 Len:16 Value:72590E8782F97E80406E4B66199B7CB2
Derived session keys:
Version 0
ENC: Ver:0 ID:0 Type:DES3 Len:16 Value:87B5171538F81656E88F60D4818CEB8A
MAC: Ver:0 ID:0 Type:DES3 Len:16 Value:E9E45A4046E1316200E9E1787A7E9CD0
KEK: Ver:0 ID:0 Type:DES3 Len:16 Value:72590E8782F97E80406E4B66199B7CB2
Verified card cryptogram: A8D1AB091B6BBE07
Calculated host cryptogram: 8E1CE84781FA24C3
A>> T=0 (4+0016) 84820100 10 8E1CE84781FA24C34BEFC7F70A76E60F
A<< (0000+2) (36ms) 9000
A>> T=0 (4+0008) 84CA00E0 08 E59D6ECDF1B764ED 00
A<< (0020+2) (13ms) E012C00401FF8110C00402FF8110C00403FF8110 9000
Replace: false
PUT KEY:Ver:1 ID:1 Type:DES3 Len:16 Value:404142434445464748494A4B4C4D4E4F
PUT KEY:Ver:1 ID:2 Type:DES3 Len:16 Value:404142434445464748494A4B4C4D4E4F
PUT KEY:Ver:1 ID:3 Type:DES3 Len:16 Value:404142434445464748494A4B4C4D4E4F
A>> T=0 (4+0008) 84CA00E0 08 2B4AD25011601191 00
A<< (0020+2) (13ms) E012C00401FF8110C00402FF8110C00403FF8110 9000
A>> T=0 (4+0075) 84D80081 4B 0180100F8DB2F2600B53F9002C36CB377D55AF038BAF4780100
F8DB2F2600B53F9002C36CB377D55AF038BAF4780100F8DB2F2600B53F9002C36CB377D55AF038BA
F47B387704000A3A1AA
A<< (0000+2) (49ms) 6A80
pro.javacard.gp.GPException: PUT KEY failed SW: 6A80
at pro.javacard.gp.GlobalPlatform.check(GlobalPlatform.java:1092)
at pro.javacard.gp.GlobalPlatform.putKeys(GlobalPlatform.java:993)
at pro.javacard.gp.GPTool.main(GPTool.java:555)
Solution: A new GlobalPlatformPro release was necessary for this specific Gemalto card.
The command that lists the applets on the card:
gp -visa2 -key 47454D5850524553534F53414D504C45 -l
Mutual authentication is a mandatory step for uploading and installing applets on smart cards(And also for listing installed applets and packages). Different cards use different cryptigraphy algoritms to do this mutual authentication procedure. It seems that your card using an algorithm that the GlobalPlatformPro does not supporting it. You must take a look at the card's datasheet to see which algorithm your card use.
About the GPShell :
There is an entity on the cards that is named "Security Domain". This entity is responsible for loading, intalling and listing applets. It has an AID and you must select it by Select APDU command. There is an AID in the list.txt script and you must replace it with the AID of the SD of your card.
And about the driver alert: It's OK! I have the same pop up alert when I insert my card in the reader, but everything works fine.
Finally, please don't try to test other tools in such this way! 10 failure in mutual authentication in a row, make the card locked.(not useable anymore).
GlobalPlatformPro README has a well-placed (well-hidden?) hint on this one:
Set the default 40..4F keys to a card that uses VISA2 diversification
with the well-known mother key on a Gemalto card:
gp -visa2 -key 47454D5850524553534F53414D504C45 -unlock
But keep in mind, that you need to know the keying material. The hints are only for well-known public cases.