diff --git a/Makefile b/Makefile index 9378403..d329bd0 100644 --- a/Makefile +++ b/Makefile @@ -1,82 +1,60 @@ -#******************************************************************************* -# Ledger App -# (c) 2016-2018 Ledger -# +# Copyright 2017 Cedric Mesnil , Ledger SAS +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -#******************************************************************************* +# ifeq ($(BOLOS_SDK),) $(error Environment variable BOLOS_SDK is not set) endif include $(BOLOS_SDK)/Makefile.defines -APP_LOAD_PARAMS=--appFlags 0x40 --path "2152157255'" --curve secp256k1 $(COMMON_LOAD_PARAMS) - -APPNAME = OpenPGP - -SPECVERSION="3.3.1" +APPNAME = "OpenPGP" +APP_LOAD_PARAMS=--appFlags 0x40 --path "2152157255" --curve secp256k1 $(COMMON_LOAD_PARAMS) APPVERSION_M=1 -APPVERSION_N=2 -APPVERSION_P=1 +APPVERSION_N=1 +APPVERSION_P=0 + APPVERSION=$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P) - -ifeq ($(TARGET_NAME),TARGET_BLUE) -ICONNAME=images/icon_pgp_blue.gif -else +SPECVERSION="3.3.1" ICONNAME=images/icon_pgp.gif -endif -DEFINES += $(GPG_CONFIG) GPG_VERSION=$(APPVERSION) GPG_NAME=$(APPNAME) SPEC_VERSION=$(SPECVERSION) ################ # Default rule # ################ - all: default ############ # Platform # ############ -#SCRIPT_LD := script.ld - -ifneq ($(NO_CONSENT),) -DEFINES += NO_CONSENT -endif - -DEFINES += OS_IO_SEPROXYHAL IO_SEPROXYHAL_BUFFER_SIZE_B=300 -DEFINES += HAVE_BAGL HAVE_SPRINTF -#DEFINES += HAVE_PRINTF PRINTF=screen_printf -DEFINES += PRINTF\(...\)= -DEFINES += HAVE_IO_USB HAVE_L4_USBLIB IO_USB_MAX_ENDPOINTS=6 IO_HID_EP_LENGTH=64 HAVE_USB_APDU -#DEFINES += HAVE_BLE -DEFINES += UNUSED\(x\)=\(void\)x -DEFINES += APPVERSION=\"$(APPVERSION)\" -DEFINES += CUSTOM_IO_APDU_BUFFER_SIZE=\(255+5+64\) +DEFINES += OS_IO_SEPROXYHAL IO_SEPROXYHAL_BUFFER_SIZE_B=128 +DEFINES += HAVE_BAGL HAVE_PRINTF HAVE_SPRINTF +DEFINES += HAVE_IO_USB HAVE_L4_USBLIB IO_USB_MAX_ENDPOINTS=7 IO_HID_EP_LENGTH=64 HAVE_USB_APDU DEFINES += HAVE_USB_CLASS_CCID +DEFINES += $(GPG_CONFIG) GPG_VERSION=$(APPVERSION) GPG_NAME=$(APPNAME) SPEC_VERSION=$(SPECVERSION) + ############## -# Compiler # +# Compiler # ############## #GCCPATH := $(BOLOS_ENV)/gcc-arm-none-eabi-5_3-2016q1/bin/ #CLANGPATH := $(BOLOS_ENV)/clang-arm-fropi/bin/ CC := $(CLANGPATH)clang #CFLAGS += -O0 -gdwarf-2 -gstrict-dwarf -CFLAGS += -O3 -Os -#CFLAGS += -fno-jump-tables -fno-lookup-tables -fsave-optimization-record -#$(info $(CFLAGS)) +CFLAGS += -O3 -Os AS := $(GCCPATH)arm-none-eabi-gcc @@ -88,9 +66,9 @@ LDLIBS += -lm -lgcc -lc # import rules to compile glyphs(/pone) include $(BOLOS_SDK)/Makefile.glyphs -### variables processed by the common makefile.rules of the SDK to grab source files and include dirs +### computed variables APP_SOURCE_PATH += src -SDK_SOURCE_PATH += lib_stusb +SDK_SOURCE_PATH += lib_stusb lib_stusb_impl load: all @@ -100,8 +78,8 @@ delete: python -m ledgerblue.deleteApp $(COMMON_DELETE_PARAMS) # import generic rules from the sdk -include Makefile.rules +include $(BOLOS_SDK)/Makefile.rules #add dependency on custom makefile filename -dep/%.d: %.c Makefile +dep/%.d: %.c Makefile.genericwallet diff --git a/Makefile.rules b/Makefile.rules deleted file mode 100644 index 7c2d312..0000000 --- a/Makefile.rules +++ /dev/null @@ -1,29 +0,0 @@ -#******************************************************************************* -# Ledger SDK -# (c) 2017 Ledger -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -#******************************************************************************* - - -#Make the SDK modified SDK sources prioritar to the original ones - -SOURCE_PATH += $(dir $(foreach libdir, $(APP_SOURCE_PATH), $(dir $(shell find $(libdir) | grep "\.c$$")))) $(BOLOS_SDK)/src $(foreach libdir, $(SDK_SOURCE_PATH), $(dir $(shell find $(BOLOS_SDK)/$(libdir) | grep "\.c$$"))) -SOURCE_FILES := $(foreach path, $(SOURCE_PATH),$(shell find $(path) | grep "\.c$$") ) $(GLYPH_DESTC) -INCLUDES_PATH := $(dir $(foreach libdir, $(APP_SOURCE_PATH), $(dir $(shell find $(libdir) | grep "\.h$$")))) $(dir $(foreach libdir, $(SDK_SOURCE_PATH), $(dir $(shell find $(BOLOS_SDK)/$(libdir) | grep "\.h$$")))) include $(BOLOS_SDK)/include $(BOLOS_SDK)/include/arm - -VPATH := $(dir $(SOURCE_FILES)) -OBJECT_FILES := $(sort $(addprefix obj/, $(addsuffix .o, $(basename $(notdir $(SOURCE_FILES)))))) -DEPEND_FILES := $(sort $(addprefix dep/, $(addsuffix .d, $(basename $(notdir $(SOURCE_FILES)))))) - -include $(BOLOS_SDK)/Makefile.rules_generic \ No newline at end of file diff --git a/doc/developper/quick-test.txt b/doc/developper/quick-test.txt deleted file mode 100644 index 5558ce7..0000000 --- a/doc/developper/quick-test.txt +++ /dev/null @@ -1,196 +0,0 @@ -Step1: ... ------ -Jump into any temp dir - - -Step2: install nanos ------ -Do a fresh install of gpg application 1.1.0 from google app manager - - -Step3: setup conf ------ -Create a 'manual-test' directory - $ mkdir manual-test - -Create a 'manual-test/gnupg' - $ mkdir manual-test/gnupg - -Create a 'manual-test/gnupg/scdaemon.conf' file with content: - reader-port "Ledger Token [Nano S] (0001) 01 00" - allow-admin - card-timeout 1 - debug-level expert - debug 11 - log-file /tmp/scdaemon.log - -Jump into manual-test dir - -Step4: change to host pin style ------ -Launch gpg NanoS application and: - $ killall scdaemon gpg-agent - $ gpg2 --homedir `pwd`/gnupg --card-edit - gpg: WARNING: unsafe permissions on homedir '/home/cme/Projects/Git/ledgerblue/blue-app-openpgp-card/manual-test/gnupg' - gpg: keybox '/home/cme/Projects/Git/ledgerblue/blue-app-openpgp-card/manual-test/gnupg/pubring.kbx' created - - Reader ...........: Ledger Token [Nano S] (0001) 01 00 - Application ID ...: D2760001240103002C97DDD38BA90000 - Version ..........: 3.0 - Manufacturer .....: unknown - Serial number ....: DDD38BA9 - Name of cardholder: [not set] - Language prefs ...: [not set] - Sex ..............: unspecified - URL of public key : [not set] - Login data .......: [not set] - Signature PIN ....: not forced - Key attributes ...: rsa2048 rsa2048 rsa2048 - Max. PIN lengths .: 12 12 12 - PIN retry counter : 3 0 3 - Signature counter : 0 - Signature key ....: [none] - Encryption key....: [none] - Authentication key: [none] - General key info..: [none] - - gpg/card> verify - - Reader ...........: Ledger Token [Nano S] (0001) 01 00 - Application ID ...: D2760001240103002C97DDD38BA90000 - Version ..........: 3.0 - Manufacturer .....: unknown - Serial number ....: DDD38BA9 - Name of cardholder: [not set] - Language prefs ...: [not set] - Sex ..............: unspecified - URL of public key : [not set] - Login data .......: [not set] - Signature PIN ....: not forced - Key attributes ...: rsa2048 rsa2048 rsa2048 - Max. PIN lengths .: 12 12 12 - PIN retry counter : 3 0 3 - Signature counter : 0 - Signature key ....: [none] - Encryption key....: [none] - Authentication key: [none] - General key info..: [none] - - gpg/card> - -Then on nanos, goto settings->PIN mode, and select 'Host' -Then on nanos, goto settings->PIN mode, and select 'Set as default' - -unplug and replug the nanos - -relaunch the openpgp application - -Goto settings->PIN mode, and check you have "Host # +" (DASH and PLUS) - - -Step5: create 2048bits RSA keys ------ - - -In 'manual-test' directory, ask key generation. Nota that during this phase PIN has to be validate on Nanos - - $ killall scdaemon gpg-agent - $ gpg2 --homedir `pwd`/gnupg --card-edit - gpg: WARNING: unsafe permissions on homedir '/home/cme/Projects/Git/ledgerblue/blue-app-openpgp-card/manual-test/gnupg' - - Reader ...........: Ledger Token [Nano S] (0001) 01 00 - Application ID ...: D2760001240103002C97DDD38BA90000 - Version ..........: 3.0 - Manufacturer .....: unknown - Serial number ....: DDD38BA9 - Name of cardholder: [not set] - Language prefs ...: [not set] - Sex ..............: unspecified - URL of public key : [not set] - Login data .......: [not set] - Signature PIN ....: not forced - Key attributes ...: rsa2048 rsa2048 rsa2048 - Max. PIN lengths .: 12 12 12 - PIN retry counter : 3 0 3 - Signature counter : 0 - Signature key ....: [none] - Encryption key....: [none] - Authentication key: [none] - General key info..: [none] - - gpg/card> admin - Admin commands are allowed - - gpg/card> generate - Make off-card backup of encryption key? (Y/n) n - - Please note that the factory settings of the PINs are - PIN = '123456' Admin PIN = '12345678' - You should change them using the command --change-pin - - What keysize do you want for the Signature key? (2048) 2048 - What keysize do you want for the Encryption key? (2048) 2048 - What keysize do you want for the Authentication key? (2048) 2048 - Please specify how long the key should be valid. - 0 = key does not expire - = key expires in n days - w = key expires in n weeks - m = key expires in n months - y = key expires in n years - Key is valid for? (0) 0 - Key does not expire at all - Is this correct? (y/N) y - - GnuPG needs to construct a user ID to identify your key. - - Real name: testkey - Email address: - Comment: - You selected this USER-ID: - "testkey" - - Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O - gpg: /home/cme/Projects/Git/ledgerblue/blue-app-openpgp-card/manual-test/gnupg/trustdb.gpg: trustdb created - gpg: key 5ED17DF289C757A2 marked as ultimately trusted - gpg: directory '/home/cme/Projects/Git/ledgerblue/blue-app-openpgp-card/manual-test/gnupg/openpgp-revocs.d' created - gpg: revocation certificate stored as '/home/cme/Projects/Git/ledgerblue/blue-app-openpgp-card/manual-test/gnupg/openpgp-revocs.d/7FDC3D2FCD3558CB06631EAB5ED17DF289C757A2.rev' - public and secret key created and signed. - - - gpg/card> quit - pub rsa2048 2017-10-03 [SC] - 7FDC3D2FCD3558CB06631EAB5ED17DF289C757A2 - uid testkey - sub rsa2048 2017-10-03 [A] - sub rsa2047 2017-10-03 [E] - - - -Step6: encrypt/decrypt ------ -encrypt - - $ killall scdaemon gpg-agent - $ echo CLEAR > foo.txt - $ gpg2 --homedir `pwd`/gnupg -e -r testkey foo.txt - gpg: WARNING: unsafe permissions on homedir '/home/cme/Projects/Git/ledgerblue/blue-app-openpgp-card/manual-test/gnupg' - gpg: checking the trustdb - gpg: marginals needed: 3 completes needed: 1 trust model: pgp - gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u - -Force pin to asked - - $ killall gpg-agent scdaemon - -decrypt - - $ gpg2 --homedir `pwd`/gnupg foo.txt.gpg - gpg: WARNING: unsafe permissions on homedir '/home/cme/Projects/Git/ledgerblue/blue-app-openpgp-card/manual-test/gnupg' - gpg: encrypted with 2047-bit RSA key, ID 602FE5EB7BFA4B00, created 2017-10-03 - "testkey" - File 'foo.txt' exists. Overwrite? (y/N) y - -Step7: pin on screen ------- - -Restart from Step1, but skip step4 diff --git a/doc/user/blue-app-openpgp-card.pdf b/doc/user/blue-app-openpgp-card.pdf index da6874f..d7e603f 100644 Binary files a/doc/user/blue-app-openpgp-card.pdf and b/doc/user/blue-app-openpgp-card.pdf differ diff --git a/doc/user/blue-app-openpgp-card.rst b/doc/user/blue-app-openpgp-card.rst index 97a778d..6709545 100644 --- a/doc/user/blue-app-openpgp-card.rst +++ b/doc/user/blue-app-openpgp-card.rst @@ -1,5 +1,5 @@ .. - Copyright 2018 Cedric Mesnil , Ledger SAS + Copyright 2017 Cedric Mesnil , Ledger SAS Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at @@ -96,7 +96,15 @@ The application is ready to use! From source ~~~~~~~~~~~~~ -Building from sources requires the the Nano S SDK 1.4.2.1 on firmware 1.4.2. See https://github.com/LedgerHQ/nanos-secure-sdk +Building from sources requires the the Nano S SDK 1.3.1.4 on firmware 1.3.1. See https://github.com/LedgerHQ/nanos-secure-sdk + +The SDK must be slightly modified: + + - replace lib_stusb/STM32_USB_Device_Library/Class/CCID/src/usbd_ccid_if.c + and lib_stusb/STM32_USB_Device_Library/Class/CCID/inc/usbd_ccid_if.h by the + one provided in sdk/ directory + - edit script.ld and modify the stack size : STACK_SIZE = 832; + Refer to the SDK documentation for the compiling/loading... @@ -113,9 +121,9 @@ Linux You have to have to add the NanoS to /etc/libccid_Info.plist - - In ifdVendorID add the entry 0x2C97 - - In ifdProductID add the entry 0x0001 - - In ifdFriendlyName add the entry Ledger Token + In ifdVendorID add the entry 0x2C97 + In ifdProductID add the entry 0x0001 + In ifdFriendlyName add the entry Ledger Token These 3 entries must be added at the end of each list. @@ -127,9 +135,9 @@ MAC 2. You have to add the Nano S to /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist - - In ifdVendorID add the entry 0x2C97 - - In ifdProductID add the entry 0x0001 - - In ifdFriendlyName add the entry Ledger Token + In ifdVendorID add the entry 0x2C97 + In ifdProductID add the entry 0x0001 + In ifdFriendlyName add the entry Ledger Token This 3 entries must be added at the end of each list. @@ -177,7 +185,6 @@ The full menu layout is : | Set on | Set off | PIN mode -| UIF mode | \ *Choose:* | Host | On Screen @@ -239,39 +246,8 @@ A key template is defined by the OpenGPG card application specification. It describes the key to be generated with the ``generate`` command in ``gpg --card-edit`` -The problem is there is no way with the ``gpg --card-edit`` command line -to easily set up the desired template, except for Ed25519. - -To set up a new ECC template you have tow choice: the NanoS menu or the -gpg-connect-agent tools. - - - -**gpg-connect-agent** (recommended) - -This method suppose you have correctly configured your GnuPG tool. -See the dedicated section for that. - -In a terminal launch : - - gpg-connect-agent "SCD SETATTR KEY-ATTR --force 1 " /bye - gpg-connect-agent "SCD SETATTR KEY-ATTR --force 2 18 " /bye - gpg-connect-agent "SCD SETATTR KEY-ATTR --force 3 " /bye - -This 3 commands fix, in that order, the template for Signature, Decryption, Authentication keys. - -Supported curve name are: - -- secp256k1 with tag 19 -- nistp256 with tag 19 -- brainpoolP256r1 with tag 19 -- cv25519 (only for key 2) -- ed25519 with tag 22 (only for key 1 and 3) - - -To show the current template use the ``gpg --card-status`` command. - -**NanoS menu** +The problem is there is no way with the ``gpg`` command line to easily set +up the desired template. The menu fixes that. First under *Choose Key* menu, select the one of three keys for which you want to modify the template. Then under "Choose Type", select the desired key template. @@ -279,11 +255,10 @@ Finally select "Set Template" entry to set it. To show the current template use the ``gpg --card-status`` command. + Seed mode ~~~~~~~~~ -**WARNING** : SEED MODE IS EXPERIMENTAL - When generating new keys on NanoS, those keys can be generated randomly or in a deterministic way. The deterministic way is specified in [GPGADD]. The current mode is displayed in the first sub menu. To activate the seeded @@ -291,7 +266,6 @@ The current mode is displayed in the first sub menu. To activate the seeded When the application starts, the seeded mode is always set to *OFF* -**WARNING** : SEED MODE IS EXPERIMENTAL PIN mode ~~~~~~~~ @@ -366,17 +340,6 @@ This is the default mode after application installation. Act as if the PIN is always validated. This is a dangerous mode which should only be used in a highly secure environment. -UIF mode -~~~~~~~~ - - -By activating UIF mode for either signature, decryption or authentication, a user validation -will be ask by the device each time the related operation is performed. - -To activate or deactivate the UIF, select the operation to protect and press both button. -When activated, a '+' symbol appears after the operation name. - - Reset ~~~~~ @@ -407,7 +370,6 @@ the reader and the delegated PIN support. Edit the file ~/.gnupg/scdaemon.conf and add the following lines: | ``reader-port "Ledger Token [Nano S] (0001) 01 00"`` - | ``allow-admin`` | ``enable-pinpad-varlen`` diff --git a/pytools/gpgcard/gpgcard.py b/pytools/gpgcard/gpgcard.py index 5d248bc..39a761c 100644 --- a/pytools/gpgcard/gpgcard.py +++ b/pytools/gpgcard/gpgcard.py @@ -163,9 +163,9 @@ class GPGCard() : sw = (sw1<<8)|sw2 #print("xch S resp: %s %.04x"%(binascii.hexlify(resp),sw)) return resp,sw - + def _disconnect_ledger(self): - return self.token.close() + return self.token.close() def _disconnect_pcsc(self): r = self.connection.disconnect() @@ -266,7 +266,7 @@ class GPGCard() : self.sig_date = dates[0:4] self.dec_date = dates[4:8] self.aut_date = dates[8:12] - + self.cardholder_cert = self.get_data(0x7f21) self.UIF_SIG,sw = self.get_data(0xD6) @@ -289,13 +289,13 @@ class GPGCard() : self.put_data(0x0102, self.private_02) self.put_data(0x0103, self.private_03) self.put_data(0x0104, self.private_04) - + self.put_data(0x5b, self.name) self.put_data(0x5e, self.login) self.put_data(0x5f2d, self.lang) self.put_data(0x5f35, self.sex) self.put_data(0x5f50, self.url) - + self.put_data(0xc1, self.sig_attribute) self.put_data(0xc2, self.dec_attribute) self.put_data(0xc3, self.aut_attribute) @@ -326,13 +326,13 @@ class GPGCard() : self.name, self.login, self.sex, self.url, self.sig_attribute, self.dec_attribute, self.aut_attribute, self.PW_status, - self.sig_fingerprints, self.dec_fingerprints, self.aut_fingerprints, - self.sig_CA_fingerprints, self.dec_CA_fingerprints, self.aut_CA_fingerprints, - self.sig_date, self.dec_date, self.aut_date, + self.sig_fingerprints, self.dec_fingerprints, self.aut_fingerprints, + self.sig_CA_fingerprints, self.dec_CA_fingerprints, self.aut_CA_fingerprints, + self.sig_date, self.dec_date, self.aut_date, self.cardholder_cert, self.UIF_SIG, self.UIF_DEC, self.UIF_AUT), f, 2) - + def restore(self, file_name, seed_key=False): f = open(file_name,mode='r+b') @@ -341,9 +341,9 @@ class GPGCard() : self.name, self.login, self.sex, self.url, self.sig_attribute, self.dec_attribute, self.aut_attribute, self.status, - self.sig_fingerprints, self.dec_fingerprints, self.aut_fingerprints, - self.sig_CA_fingerprints, self.dec_CA_fingerprints, self.aut_CA_fingerprints, - self.sig_date, self.dec_date, self.aut_date, + self.sig_fingerprints, self.dec_fingerprints, self.aut_fingerprints, + self.sig_CA_fingerprints, self.dec_CA_fingerprints, self.aut_CA_fingerprints, + self.sig_date, self.dec_date, self.aut_date, self.cardholder_cert, self.UIF_SIG, self.UIF_DEC, self.UIF_AUT) = pickle.load(f) self.set_all() diff --git a/pytools/gpgcard/restore_perso.py b/pytools/gpgcard/restore_perso.py deleted file mode 100644 index 9c20560..0000000 --- a/pytools/gpgcard/restore_perso.py +++ /dev/null @@ -1,35 +0,0 @@ -import binascii - -from gpgcard import GPGCard - -print("Connecting to device ...") -gpgcard = GPGCard() -gpgcard.connect("pcsc:Ledger") -gpgcard.get_all() - -gpgcard.verify_pin(0x81, "123456") -gpgcard.verify_pin(0x83, "12345678") - -print("Generating key 1/3 ...") -gpgcard.generate_asym_key_pair(0x80, 0xb600) -print("Generating key 2/3 ...") -gpgcard.generate_asym_key_pair(0x80, 0xb800) -print("Generating key 3/3 ...") -gpgcard.generate_asym_key_pair(0x80, 0xa400) - -# Use 'gpg -k --with-subkey-fingerprint' to find fingerprints - -print("Setting fingerprints ...") -sig_fingerprint = b'A3F35A5124D47C3195FF07B7F85D93686A3A9063' -aut_fingerprint = b'9C686F97A39B4A34E0C9D37CDBF45893AB524BBC' -dec_fingerprint = b'E4FE54969060DBF2756FC0EFD8203245E390CAEA' - -sig_fingerprint_bin = binascii.unhexlify(sig_fingerprint) -aut_fingerprint_bin = binascii.unhexlify(aut_fingerprint) -dec_fingerprint_bin = binascii.unhexlify(dec_fingerprint) - -gpgcard.sig_fingerprints = sig_fingerprint_bin -gpgcard.aut_fingerprints = aut_fingerprint_bin -gpgcard.dec_fingerprints = dec_fingerprint_bin - -gpgcard.set_all() diff --git a/script.ld b/script.ld deleted file mode 100644 index 60b4ced..0000000 --- a/script.ld +++ /dev/null @@ -1,167 +0,0 @@ -/******************************************************************************* -* Ledger Blue - Secure firmware -* (c) 2016, 2017 Ledger -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -/** - * Global chip memory layout and constants - * - */ - -MEMORY -{ - DISCARD (rwx) : ORIGIN = 0xd0000000, LENGTH = 1M - - FLASH (rx) : ORIGIN = 0xc0d00000, LENGTH = 400K - SRAM (rwx) : ORIGIN = 0x20001800, LENGTH = 4K -} - -PAGE_SIZE = 64; -STACK_SIZE = 768; -END_STACK = ORIGIN(SRAM) + LENGTH(SRAM); - -SECTIONS -{ - ENTRY(main) - - /****************************************************************/ - /* This section locates the code in FLASH */ - /****************************************************************/ - - /** put text in Flash memory, VMA will be equal to LMA */ - .text : - { - /* provide start code symbol, shall be zero */ - _text = .; - _nvram = .; - - PROVIDE(_setjmp = setjmp); /*thanks clang*/ - - /* ensure main is always @ 0xC0D00000 */ - *(.boot*) - - /* place the other code and rodata defined BUT nvram variables that are displaced in a r/w area */ - *(.text*) - *(.rodata.[^UN]*) /*.data.rel.ro* not here to detect invalid PIC usage */ - *(.rodata.N[^_]*) - - . = ALIGN(4); - - /* all code placed */ - _etext = .; - - . = ALIGN(PAGE_SIZE); - - _nvram_data = .; - - /* NVM data (ex-filesystem) */ - *(.rodata.USBD_CfgDesc) - *(.bss.N_* .rodata.N_* .rodata.USBD_CfgDesc) - . = ALIGN(PAGE_SIZE); - _install_parameters = .; - PROVIDE(N_install_parameters = .); - _envram = .; - _nvram_data_size = _envram - _nvram_data; - - } > FLASH = 0x00 - - .data (NOLOAD): - { - . = ALIGN(4); - - /** - * Place RAM initialized variables - */ - _data = .; - - *(vtable) - *(.data*) - - _edata = .; - - } > DISCARD /*> SRAM AT>FLASH = 0x00 */ - - .bss : - { - /** - * Place RAM uninitialized variables - */ - _bss = .; - *(.bss*) - _ebss = .; - - - /** - * Reserve stack size - */ - . = ALIGN(4); - app_stack_canary = .; - PROVIDE(app_stack_canary = .); - . += 4; - _stack = .; - . = _stack + STACK_SIZE; - PROVIDE( _stack_size = STACK_SIZE ); - PROVIDE( _estack = ABSOLUTE(END_STACK) ); - - } > SRAM = 0x00 - - /****************************************************************/ - /* DEBUG */ - /****************************************************************/ - - /* remove the debugging information from the standard libraries */ - DEBUG (NOLOAD) : - { - libc.a ( * ) - libm.a ( * ) - libgcc.a ( * ) - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } - - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - /* DWARF debug sections. - Symbols in the DWARF debugging sections are relative to the beginning - of the section so we begin them at 0. */ - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } - -} diff --git a/src/sdk/usbd_ccid_if.c b/sdk/usbd_ccid_if.c old mode 100755 new mode 100644 similarity index 58% rename from src/sdk/usbd_ccid_if.c rename to sdk/usbd_ccid_if.c index a709032..b212737 --- a/src/sdk/usbd_ccid_if.c +++ b/sdk/usbd_ccid_if.c @@ -25,23 +25,27 @@ ****************************************************************************** */ -#pragma message "Override SDK source file :" __FILE__ - /* Includes ------------------------------------------------------------------*/ -#include "os.h" #include "usbd_ccid_if.h" #ifdef HAVE_USB_CLASS_CCID -#if CCID_BULK_EPIN_SIZE > USB_SEGMENT_SIZE - #error configuration error, the USB MAX SEGMENT SIZE does not support the CCID endpoint (CCID_BULK_EPIN_SIZE vs USB_SEGMENT_SIZE) -#endif - /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ -usb_class_ccid_t G_io_ccid; +uint8_t Ccid_BulkState; +uint8_t ccid_card_inserted; +uint8_t UsbIntMessageBuffer[INTR_MAX_PACKET_SIZE]; /* data buffer*/ +__IO uint8_t PrevXferComplete_IntrIn; +usb_ccid_param_t usb_ccid_param; + +uint8_t* pUsbMessageBuffer; +static uint32_t UsbMessageLength; +Ccid_SlotStatus_t Ccid_SlotStatus; +Protocol0_DataStructure_t Protocol0_DataStructure; + +Ccid_bulk_data_t Ccid_bulk_data; /* Private function prototypes -----------------------------------------------*/ static void CCID_Response_SendData (USBD_HandleTypeDef *pdev, @@ -56,17 +60,23 @@ static void CCID_Response_SendData (USBD_HandleTypeDef *pdev, */ void CCID_Init (USBD_HandleTypeDef *pdev) { - memset(&G_io_ccid, 0, sizeof(G_io_ccid)); - + memset(&Ccid_BulkState, 0, sizeof(Ccid_BulkState)); + memset(&UsbIntMessageBuffer, 0, sizeof(UsbIntMessageBuffer)); + memset(&PrevXferComplete_IntrIn, 0, sizeof(PrevXferComplete_IntrIn)); + memset(&usb_ccid_param, 0, sizeof(usb_ccid_param)); + memset(&pUsbMessageBuffer, 0, sizeof(pUsbMessageBuffer)); + memset(&UsbMessageLength, 0, sizeof(UsbMessageLength)); + memset(&Ccid_SlotStatus, 0, sizeof(Ccid_SlotStatus)); + memset(&Protocol0_DataStructure, 0, sizeof(Protocol0_DataStructure)); + memset(&Ccid_bulk_data, 0, sizeof(Ccid_bulk_data)); + ccid_card_inserted = 0; /* CCID Related Initialization */ -#ifdef HAVE_CCID_INTERRUPT CCID_SetIntrTransferStatus(1); /* Transfer Complete Status */ -#endif // HAVE_CCID_INTERRUPT CCID_UpdSlotChange(1); SC_InitParams(); /* Prepare Out endpoint to receive 1st packet */ - G_io_ccid.Ccid_BulkState = CCID_STATE_IDLE; + Ccid_BulkState = CCID_STATE_IDLE; USBD_LL_PrepareReceive(pdev, CCID_BULK_OUT_EP, CCID_BULK_EPOUT_SIZE); // send the smartcard as inserted state at boot time @@ -82,7 +92,7 @@ void CCID_Init (USBD_HandleTypeDef *pdev) void CCID_DeInit (USBD_HandleTypeDef *pdev) { UNUSED(pdev); - G_io_ccid.Ccid_BulkState = CCID_STATE_IDLE; + Ccid_BulkState = CCID_STATE_IDLE; } /** @@ -100,50 +110,43 @@ void CCID_BulkMessage_In (USBD_HandleTypeDef *pdev, /*************** Handle Bulk Transfer IN data completion *****************/ - switch (G_io_ccid.Ccid_BulkState) + switch (Ccid_BulkState) { case CCID_STATE_SEND_RESP: { - unsigned int remLen = G_io_ccid.UsbMessageLength; + unsigned int remLen = UsbMessageLength; // advance with acknowledged sent chunk - if (G_io_ccid.pUsbMessageBuffer == &G_io_ccid.bulk_header) { - // first part of the bulk in sent. - // advance in the data buffer to transmit. (mixed source leap) - G_io_ccid.pUsbMessageBuffer = G_io_ccid_data_buffer+MIN(CCID_BULK_EPIN_SIZE, G_io_ccid.UsbMessageLength)-CCID_HEADER_SIZE; - } - else { - G_io_ccid.pUsbMessageBuffer += MIN(CCID_BULK_EPIN_SIZE, G_io_ccid.UsbMessageLength); - } - G_io_ccid.UsbMessageLength -= MIN(CCID_BULK_EPIN_SIZE, G_io_ccid.UsbMessageLength); + pUsbMessageBuffer += MIN(CCID_BULK_EPIN_SIZE, UsbMessageLength); + UsbMessageLength -= MIN(CCID_BULK_EPIN_SIZE, UsbMessageLength); // if remaining length is > EPIN_SIZE: send a filled bulk packet - if (G_io_ccid.UsbMessageLength >= CCID_BULK_EPIN_SIZE) { - CCID_Response_SendData(pdev, G_io_ccid.pUsbMessageBuffer, + if (UsbMessageLength >= CCID_BULK_EPIN_SIZE) { + CCID_Response_SendData(pdev, pUsbMessageBuffer, // use the header declared size packet must be well formed CCID_BULK_EPIN_SIZE); } // if remaining length is 0; send an empty packet and prepare to receive a new command - else if (G_io_ccid.UsbMessageLength == 0 && remLen == CCID_BULK_EPIN_SIZE) { - CCID_Response_SendData(pdev, G_io_ccid.pUsbMessageBuffer, + else if (UsbMessageLength == 0 && remLen == CCID_BULK_EPIN_SIZE) { + CCID_Response_SendData(pdev, pUsbMessageBuffer, // use the header declared size packet must be well formed 0); goto last_xfer; // won't wait ack to avoid missing a command } // else if no more data, then last packet sent, go back to idle (done on transfer ack) - else if (G_io_ccid.UsbMessageLength == 0) { // robustness only + else if (UsbMessageLength == 0) { // robustness only last_xfer: - G_io_ccid.Ccid_BulkState = CCID_STATE_IDLE; + Ccid_BulkState = CCID_STATE_IDLE; /* Prepare EP to Receive First Cmd */ - // not timeout compliant // USBD_LL_PrepareReceive(pdev, CCID_BULK_OUT_EP, CCID_BULK_EPOUT_SIZE); + USBD_LL_PrepareReceive(pdev, CCID_BULK_OUT_EP, CCID_BULK_EPOUT_SIZE); } // if remaining length is < EPIN_SIZE: send packet and prepare to receive a new command - else if (G_io_ccid.UsbMessageLength < CCID_BULK_EPIN_SIZE) { - CCID_Response_SendData(pdev, G_io_ccid.pUsbMessageBuffer, + else if (UsbMessageLength < CCID_BULK_EPIN_SIZE) { + CCID_Response_SendData(pdev, pUsbMessageBuffer, // use the header declared size packet must be well formed - G_io_ccid.UsbMessageLength); + UsbMessageLength); goto last_xfer; // won't wait ack to avoid missing a command } @@ -154,35 +157,11 @@ void CCID_BulkMessage_In (USBD_HandleTypeDef *pdev, break; } } -#ifdef HAVE_CCID_INTERRUPT else if (epnum == (CCID_INTR_IN_EP & 0x7F)) { /* Filter the epnum by masking with 0x7f (mask of IN Direction) */ CCID_SetIntrTransferStatus(1); /* Transfer Complete Status */ } -#endif // HAVE_CCID_INTERRUPT -} - -void CCID_Send_Reply(USBD_HandleTypeDef *pdev) { - /********** Decide for all commands ***************/ - if (G_io_ccid.Ccid_BulkState == CCID_STATE_SEND_RESP) - { - G_io_ccid.UsbMessageLength = G_io_ccid.bulk_header.bulkin.dwLength+CCID_HEADER_SIZE; /* Store for future use */ - - /* Expected Data Length Packet Received */ - G_io_ccid.pUsbMessageBuffer = (uint8_t*) &G_io_ccid.bulk_header; - - // send bulk header and first pat of the message at once - os_memmove(G_io_usb_ep_buffer, &G_io_ccid.bulk_header, CCID_HEADER_SIZE); - if (G_io_ccid.UsbMessageLength>CCID_HEADER_SIZE) { - // copy start of data if bigger size than a header - os_memmove(G_io_usb_ep_buffer+CCID_HEADER_SIZE, G_io_ccid_data_buffer, MIN(CCID_BULK_EPIN_SIZE, G_io_ccid.UsbMessageLength)-CCID_HEADER_SIZE); - } - // send the first mixed source chunk - CCID_Response_SendData(pdev, G_io_usb_ep_buffer, - // use the header declared size packet must be well formed - MIN(CCID_BULK_EPIN_SIZE, G_io_ccid.UsbMessageLength)); - } } /** @@ -195,113 +174,123 @@ void CCID_Send_Reply(USBD_HandleTypeDef *pdev) { void CCID_BulkMessage_Out (USBD_HandleTypeDef *pdev, uint8_t epnum, uint8_t* buffer, uint16_t dataLen) { - if (epnum == (CCID_BULK_OUT_EP & 0x7F)) { - switch (G_io_ccid.Ccid_BulkState) + + switch (Ccid_BulkState) + { + case CCID_STATE_IDLE: + if (dataLen == 0x00) + { /* Zero Length Packet Received */ + Ccid_BulkState = CCID_STATE_IDLE; + } + else if (dataLen >= CCID_MESSAGE_HEADER_SIZE) { - - // after a timeout, could be in almost any state :) therefore, clean it and process the newly received command - default: - G_io_ccid.Ccid_BulkState = CCID_STATE_IDLE; - // no break is intentional - - case CCID_STATE_IDLE: - // prepare to receive another packet later on (to avoid troubles with timeout due to other hid command timeouting the ccid endpoint reply) - USBD_LL_PrepareReceive(pdev, CCID_BULK_OUT_EP, CCID_BULK_EPOUT_SIZE); - - if (dataLen == 0x00) - { /* Zero Length Packet Received, end of transfer */ - G_io_ccid.Ccid_BulkState = CCID_STATE_IDLE; - } - else if (dataLen >= CCID_HEADER_SIZE) - { - G_io_ccid.UsbMessageLength = dataLen; /* Store for future use */ - - /* Expected Data Length Packet Received */ - // endianness is little :) useful for our ARM convention - G_io_ccid.pUsbMessageBuffer = (uint8_t*) &G_io_ccid.bulk_header; - - // copy the ccid bulk header only - os_memmove(G_io_ccid.pUsbMessageBuffer, buffer, CCID_HEADER_SIZE); - // copy remaining part in the data buffer (split from the ccid to allow for overlaying with another ressource buffer) - if (dataLen>CCID_HEADER_SIZE) { - os_memmove(G_io_ccid_data_buffer, buffer+CCID_HEADER_SIZE, dataLen-CCID_HEADER_SIZE); - // we're now receiving in the data buffer (all subsequent calls) - G_io_ccid.pUsbMessageBuffer = G_io_ccid_data_buffer; - } - - if (G_io_ccid.bulk_header.bulkout.dwLength > IO_CCID_DATA_BUFFER_SIZE) - { /* Check if length of data to be sent by host is > buffer size */ - - /* Too long data received.... Error ! */ - G_io_ccid.Ccid_BulkState = CCID_STATE_UNCORRECT_LENGTH; - } - else - // everything received in the first packet - if (G_io_ccid.UsbMessageLength == (G_io_ccid.bulk_header.bulkout.dwLength + CCID_HEADER_SIZE)) { - /* Short message, less than the EP Out Size, execute the command, - if parameter like dwLength is too big, the appropriate command will - give an error */ - CCID_CmdDecode(pdev); - } - else - { /* Long message, receive additional data with command */ - G_io_ccid.Ccid_BulkState = CCID_STATE_RECEIVE_DATA; - G_io_ccid.pUsbMessageBuffer += dataLen-CCID_HEADER_SIZE; /* Point to new offset */ - } - } - break; + UsbMessageLength = dataLen; /* Store for future use */ - case CCID_STATE_RECEIVE_DATA: - - USBD_LL_PrepareReceive(pdev, CCID_BULK_OUT_EP, CCID_BULK_EPOUT_SIZE); + /* Expected Data Length Packet Received */ + pUsbMessageBuffer = (uint8_t*) &Ccid_bulk_data; - G_io_ccid.UsbMessageLength += dataLen; + /* Fill CCID_BulkOut Data Buffer from USB Buffer */ + memmove(pUsbMessageBuffer, buffer, dataLen); + + /* + Refer : 6 CCID Messages + The response messages always contain the exact same slot number, + and sequence number fields from the header that was contained in + the Bulk-OUT command message. + */ + Ccid_bulk_data.header.bulkin.bSlot = Ccid_bulk_data.header.bulkout.bSlot; + Ccid_bulk_data.header.bulkin.bSeq = Ccid_bulk_data.header.bulkout.bSeq; if (dataLen < CCID_BULK_EPOUT_SIZE) {/* Short message, less than the EP Out Size, execute the command, - if parameter like dwLength is too big, the appropriate command will - give an error */ - - /* Full command is received, process the Command */ - os_memmove(G_io_ccid.pUsbMessageBuffer, buffer, dataLen); - CCID_CmdDecode(pdev); + if parameter like dwLength is too big, the appropriate command will + give an error */ + CCID_CmdDecode(pdev); } - else //if (dataLen == CCID_BULK_EPOUT_SIZE) - { - if (G_io_ccid.UsbMessageLength < (G_io_ccid.bulk_header.bulkout.dwLength + CCID_HEADER_SIZE)) - { - os_memmove(G_io_ccid.pUsbMessageBuffer, buffer, dataLen); - G_io_ccid.pUsbMessageBuffer += dataLen; - /* Increment the pointer to receive more data */ + else + { /* Long message, receive additional data with command */ + /* (u8dataLen == CCID_BULK_EPOUT_SIZE) */ + + if (Ccid_bulk_data.header.bulkout.dwLength > ABDATA_SIZE) + { /* Check if length of data to be sent by host is > buffer size */ + + /* Too long data received.... Error ! */ + Ccid_BulkState = CCID_STATE_UNCORRECT_LENGTH; + } + + else + { /* Expect more data on OUT EP */ + Ccid_BulkState = CCID_STATE_RECEIVE_DATA; + pUsbMessageBuffer += dataLen; /* Point to new offset */ /* Prepare EP to Receive next Cmd */ - // not timeout compliant // USBD_LL_PrepareReceive(pdev, CCID_BULK_OUT_EP, CCID_BULK_EPOUT_SIZE); - } - else if (G_io_ccid.UsbMessageLength == (G_io_ccid.bulk_header.bulkout.dwLength + CCID_HEADER_SIZE)) - { - /* Full command is received, process the Command */ - os_memmove(G_io_ccid.pUsbMessageBuffer, buffer, dataLen); - CCID_CmdDecode(pdev); - } - else - { - /* Too long data received.... Error ! */ - G_io_ccid.Ccid_BulkState = CCID_STATE_UNCORRECT_LENGTH; - } - } + USBD_LL_PrepareReceive(pdev, CCID_BULK_OUT_EP, CCID_BULK_EPOUT_SIZE); + + } /* if (dataLen == CCID_BULK_EPOUT_SIZE) ends */ + } /* if (dataLen >= CCID_BULK_EPOUT_SIZE) ends */ + } /* if (dataLen >= CCID_MESSAGE_HEADER_SIZE) ends */ + break; + + case CCID_STATE_RECEIVE_DATA: + + UsbMessageLength += dataLen; + + if (dataLen < CCID_BULK_EPOUT_SIZE) + {/* Short message, less than the EP Out Size, execute the command, + if parameter like dwLength is too big, the appropriate command will + give an error */ - break; - - /* - case CCID_STATE_UNCORRECT_LENGTH: - G_io_ccid.Ccid_BulkState = CCID_STATE_IDLE; - break; - - default: - - break; - */ + /* Full command is received, process the Command */ + memmove(pUsbMessageBuffer, buffer, dataLen); + CCID_CmdDecode(pdev); } + else if (dataLen == CCID_BULK_EPOUT_SIZE) + { + if (UsbMessageLength < (Ccid_bulk_data.header.bulkout.dwLength + CCID_CMD_HEADER_SIZE)) + { + memmove(pUsbMessageBuffer, buffer, dataLen); + pUsbMessageBuffer += dataLen; + /* Increment the pointer to receive more data */ + + /* Prepare EP to Receive next Cmd */ + USBD_LL_PrepareReceive(pdev, CCID_BULK_OUT_EP, CCID_BULK_EPOUT_SIZE); + } + else if (UsbMessageLength == (Ccid_bulk_data.header.bulkout.dwLength + CCID_CMD_HEADER_SIZE)) + { + /* Full command is received, process the Command */ + memmove(pUsbMessageBuffer, buffer, dataLen); + CCID_CmdDecode(pdev); + } + else + { + /* Too long data received.... Error ! */ + Ccid_BulkState = CCID_STATE_UNCORRECT_LENGTH; + } + } + + break; + + case CCID_STATE_UNCORRECT_LENGTH: + Ccid_BulkState = CCID_STATE_IDLE; + break; + + default: + break; + } +} + +void CCID_Send_Reply(USBD_HandleTypeDef *pdev) { + /********** Decide for all commands ***************/ + if (Ccid_BulkState == CCID_STATE_SEND_RESP) + { + UsbMessageLength = Ccid_bulk_data.header.bulkin.dwLength+CCID_MESSAGE_HEADER_SIZE; /* Store for future use */ + + /* Expected Data Length Packet Received */ + pUsbMessageBuffer = (uint8_t*) &Ccid_bulk_data; + + CCID_Response_SendData(pdev, pUsbMessageBuffer, + // use the header declared size packet must be well formed + MIN(CCID_BULK_EPIN_SIZE, UsbMessageLength)); } } @@ -315,7 +304,7 @@ void CCID_CmdDecode(USBD_HandleTypeDef *pdev) { uint8_t errorCode; - switch (G_io_ccid.bulk_header.bulkout.bMessageType) + switch (Ccid_bulk_data.header.bulkout.bMessageType) { case PC_TO_RDR_ICCPOWERON: errorCode = PC_to_RDR_IccPowerOn(); @@ -391,7 +380,7 @@ void CCID_CmdDecode(USBD_HandleTypeDef *pdev) void Transfer_Data_Request(void) { /********** Update Global Variables ***************/ - G_io_ccid.Ccid_BulkState = CCID_STATE_SEND_RESP; + Ccid_BulkState = CCID_STATE_SEND_RESP; } @@ -407,7 +396,6 @@ static void CCID_Response_SendData(USBD_HandleTypeDef *pdev, uint8_t* buf, uint16_t len) { - UNUSED(pdev); // don't ask the MCU to perform bulk split, we could quickly get into a buffer overflow if (len > CCID_BULK_EPIN_SIZE) { THROW(EXCEPTION_IO_OVERFLOW); @@ -423,7 +411,6 @@ static void CCID_Response_SendData(USBD_HandleTypeDef *pdev, io_seproxyhal_spi_send(buf, len); } -#ifdef HAVE_CCID_INTERRUPT /** * @brief CCID_IntMessage * Send the Interrupt-IN data to the host @@ -432,14 +419,11 @@ static void CCID_Response_SendData(USBD_HandleTypeDef *pdev, */ void CCID_IntMessage(USBD_HandleTypeDef *pdev) { - UNUSED(pdev); /* Check if there us change in Smartcard Slot status */ if ( CCID_IsSlotStatusChange() && CCID_IsIntrTransferComplete() ) { -#ifdef HAVE_CCID_INTERRUPT /* Check Slot Status is changed. Card is Removed/ Fitted */ RDR_to_PC_NotifySlotChange(); -#endif // HAVE_CCID_INTERRUPT CCID_SetIntrTransferStatus(0); /* Reset the Status */ CCID_UpdSlotChange(0); /* Reset the Status of Slot Change */ @@ -451,7 +435,7 @@ void CCID_IntMessage(USBD_HandleTypeDef *pdev) G_io_seproxyhal_spi_buffer[4] = SEPROXYHAL_TAG_USB_EP_PREPARE_DIR_IN; G_io_seproxyhal_spi_buffer[5] = 2; io_seproxyhal_spi_send(G_io_seproxyhal_spi_buffer, 6); - io_seproxyhal_spi_send(G_io_ccid.UsbIntMessageBuffer, 2); + io_seproxyhal_spi_send(UsbIntMessageBuffer, 2); } } @@ -463,7 +447,7 @@ void CCID_IntMessage(USBD_HandleTypeDef *pdev) */ uint8_t CCID_IsIntrTransferComplete (void) { - return G_io_ccid.PrevXferComplete_IntrIn; + return PrevXferComplete_IntrIn; } /** @@ -474,9 +458,8 @@ uint8_t CCID_IsIntrTransferComplete (void) */ void CCID_SetIntrTransferStatus (uint8_t xfer_Status) { - G_io_ccid.PrevXferComplete_IntrIn = xfer_Status; + PrevXferComplete_IntrIn = xfer_Status; } -#endif // HAVE_CCID_INTERRUPT @@ -484,7 +467,12 @@ void CCID_SetIntrTransferStatus (uint8_t xfer_Status) uint8_t SC_Detect(void) { - return G_io_ccid.ccid_card_inserted; + return ccid_card_inserted; +} + +void SC_Poweroff(void) { + // nothing to do + } void SC_InitParams (void) { @@ -492,72 +480,64 @@ void SC_InitParams (void) { } uint8_t SC_SetParams (Protocol0_DataStructure_t* pt0) { - UNUSED(pt0); return SLOT_NO_ERROR; } - +uint8_t SC_ExecuteEscape (uint8_t* escapePtr, uint32_t escapeLen, + uint8_t* responseBuff, + uint16_t* responseLen) { + io_seproxyhal_se_reset(); +} uint8_t SC_SetClock (uint8_t bClockCommand) { - UNUSED(bClockCommand); return SLOT_NO_ERROR; } - uint8_t SC_Request_GetClockFrequencies(uint8_t* pbuf, uint16_t* len); uint8_t SC_Request_GetDataRates(uint8_t* pbuf, uint16_t* len); uint8_t SC_T0Apdu(uint8_t bmChanges, uint8_t bClassGetResponse, uint8_t bClassEnvelope) { - UNUSED(bmChanges); - UNUSED(bClassGetResponse); - UNUSED(bClassEnvelope); return SLOTERROR_CMD_NOT_SUPPORTED; } uint8_t SC_Mechanical(uint8_t bFunction) { - UNUSED(bFunction); return SLOTERROR_CMD_NOT_SUPPORTED; } uint8_t SC_SetDataRateAndClockFrequency(uint32_t dwClockFrequency, uint32_t dwDataRate) { - UNUSED(dwClockFrequency); - UNUSED(dwDataRate); return SLOT_NO_ERROR; } + uint8_t SC_Secure(uint32_t dwLength, uint8_t bBWI, uint16_t wLevelParameter, uint8_t* pbuf, uint32_t* returnLen ) { - UNUSED(bBWI); - UNUSED(wLevelParameter); - UNUSED(returnLen); // return SLOTERROR_CMD_NOT_SUPPORTED; uint16_t ret_len,off; - switch(pbuf[0]) - { - case 0: // verify pin - off = 15; - //ret_len = dwLength - 15; - ret_len = 5; - break; - case 1: // modify pin - switch(pbuf[11]) - { - case 3: - off = 20; + switch(pbuf[0]) { + case 0: // verify pin + //ret_len = dwLength - 15; + ret_len = 5; + off = 15; break; - case 2: - case 1: - off = 19; + + case 1: // modify pin + switch(pbuf[11]) { + case 3: + off = 20; + break; + case 2: + case 1: + off = 19; + break; + default: + off = 18; + break; + } + //ret_len = dwLength - off; + ret_len = 5; break; - // 0 and 4-0xFF - default: - off = 18; - break; - } - //ret_len = dwLength - off; - ret_len = 5; - break; - default: // unsupported - G_io_ccid.bulk_header.bulkin.dwLength = 0; - RDR_to_PC_DataBlock(SLOTERROR_CMD_NOT_SUPPORTED); - CCID_Send_Reply(&USBD_Device); - return SLOTERROR_CMD_NOT_SUPPORTED; + + default: // unsupported + Ccid_bulk_data.header.bulkin.dwLength = 0; + RDR_to_PC_DataBlock(SLOTERROR_CMD_NOT_SUPPORTED); + CCID_Send_Reply(&USBD_Device); + return SLOTERROR_CMD_NOT_SUPPORTED; } pbuf += off; pbuf[0] = 0xEF; @@ -566,15 +546,13 @@ uint8_t SC_Secure(uint32_t dwLength, uint8_t bBWI, uint16_t wLevelParameter, // prepare the apdu to be processed by the application uint8_t SC_XferBlock (uint8_t* ptrBlock, uint32_t blockLen, uint16_t* expectedLen) { - UNUSED(expectedLen); - // check for overflow if (blockLen > IO_APDU_BUFFER_SIZE) { return SLOTERROR_BAD_LENTGH; } - // copy received apdu // if G_io_ccid_data_buffer is the buffer apdu, then the memmove will do nothing - os_memmove(G_io_apdu_buffer, ptrBlock, blockLen); + // copy received apdu + memmove(G_io_apdu_buffer, ptrBlock, blockLen); G_io_apdu_length = blockLen; G_io_apdu_media = IO_APDU_MEDIA_USB_CCID; // for application code G_io_apdu_state = APDU_USB_CCID; // for next call to io_exchange @@ -584,26 +562,23 @@ uint8_t SC_XferBlock (uint8_t* ptrBlock, uint32_t blockLen, uint16_t* expectedLe void io_usb_ccid_reply(unsigned char* buffer, unsigned short length) { // avoid memory overflow - if (length > IO_CCID_DATA_BUFFER_SIZE) { + if (length > sizeof(Ccid_bulk_data.abData)) { THROW(EXCEPTION_IO_OVERFLOW); } // copy the responde apdu - os_memmove(G_io_ccid_data_buffer, buffer, length); - G_io_ccid.bulk_header.bulkin.dwLength = length; + memmove(Ccid_bulk_data.abData, buffer, length); + Ccid_bulk_data.header.bulkin.dwLength = length; // forge reply RDR_to_PC_DataBlock(SLOT_NO_ERROR); // start sending rpely CCID_Send_Reply(&USBD_Device); } - // ask for power on void io_usb_ccid_set_card_inserted(unsigned int inserted) { - G_io_ccid.ccid_card_inserted = inserted; + ccid_card_inserted = inserted; CCID_UpdSlotChange(1); -#ifdef HAVE_CCID_INTERRUPT CCID_IntMessage(&USBD_Device); -#endif // HAVE_CCID_INTERRUPT } @@ -611,7 +586,6 @@ void io_usb_ccid_set_card_inserted(unsigned int inserted) { - #endif // HAVE_USB_CLASS_CCID /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/sdk/usbd_ccid_if.h b/sdk/usbd_ccid_if.h new file mode 100755 index 0000000..78e042f --- /dev/null +++ b/sdk/usbd_ccid_if.h @@ -0,0 +1,209 @@ +/** + ****************************************************************************** + * @file usbd_ccid_if.h + * @author MCD Application Team + * @version V1.0.1 + * @date 31-January-2014 + * @brief This file provides all the functions prototypes for USB CCID + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_CCID_IF_H +#define __USBD_CCID_IF_H + +#include "usbd_core.h" + +#ifdef HAVE_USB_CLASS_CCID + + +/* Exported defines ----------------------------------------------------------*/ +/* Bulk-only Command Block Wrapper */ +#define ABDATA_SIZE 261 +#define CCID_CMD_HEADER_SIZE 10 +#define CCID_RESPONSE_HEADER_SIZE 10 + + +#define CCID_INT_BUFF_SIZ 2 + +#define CARD_SLOT_FITTED 1 +#define CARD_SLOT_REMOVED 0 + +#define BULK_MAX_PACKET_SIZE 0x40 +#define CCID_IN_EP_SIZE 0x40 +#define INTR_MAX_PACKET_SIZE 8 +#define CCID_MESSAGE_HEADER_SIZE 10 +#define CCID_NUMBER_OF_SLOTS 1 + /* Number of SLOTS. For single card, this value is 1 */ + +/* Following Parameters used in PC_to_RDR_IccPowerOn */ +#define VOLTAGE_SELECTION_AUTOMATIC 0xFF +#define VOLTAGE_SELECTION_3V 0x02 +#define VOLTAGE_SELECTION_5V 0x01 +#define VOLTAGE_SELECTION_1V8 0x03 + +#define PC_TO_RDR_ICCPOWERON 0x62 +#define PC_TO_RDR_ICCPOWEROFF 0x63 +#define PC_TO_RDR_GETSLOTSTATUS 0x65 +#define PC_TO_RDR_XFRBLOCK 0x6F +#define PC_TO_RDR_GETPARAMETERS 0x6C +#define PC_TO_RDR_RESETPARAMETERS 0x6D +#define PC_TO_RDR_SETPARAMETERS 0x61 +#define PC_TO_RDR_ESCAPE 0x6B +#define PC_TO_RDR_ICCCLOCK 0x6E +#define PC_TO_RDR_T0APDU 0x6A +#define PC_TO_RDR_SECURE 0x69 +#define PC_TO_RDR_MECHANICAL 0x71 +#define PC_TO_RDR_ABORT 0x72 +#define PC_TO_RDR_SETDATARATEANDCLOCKFREQUENCY 0x73 + +#define RDR_TO_PC_DATABLOCK 0x80 +#define RDR_TO_PC_SLOTSTATUS 0x81 +#define RDR_TO_PC_PARAMETERS 0x82 +#define RDR_TO_PC_ESCAPE 0x83 +#define RDR_TO_PC_DATARATEANDCLOCKFREQUENCY 0x84 + +#define RDR_TO_PC_NOTIFYSLOTCHANGE 0x50 +#define RDR_TO_PC_HARDWAREERROR 0x51 + +#define OFFSET_INT_BMESSAGETYPE 0 +#define OFFSET_INT_BMSLOTICCSTATE 1 +#define SLOT_ICC_PRESENT 0x01 + /* LSb : (0b = no ICC present, 1b = ICC present) */ + +#define SLOT_ICC_CHANGE 0x02 /* MSb : (0b = no change, 1b = change) */ +/*****************************************************************************/ +/*********************** CCID Bulk Transfer State machine ********************/ +/*****************************************************************************/ +#define CCID_STATE_IDLE 0 /* Idle state */ +#define CCID_STATE_DATA_OUT 1 /* Data Out state */ +#define CCID_STATE_RECEIVE_DATA 2 +#define CCID_STATE_SEND_RESP 3 +#define CCID_STATE_DATAIN 4 +#define CCID_STATE_UNCORRECT_LENGTH 5 + +#define DIR_IN 0 +#define DIR_OUT 1 +#define BOTH_DIR 2 + +/* Exported types ------------------------------------------------------------*/ +#pragma pack(1) +typedef struct +{ + #pragma pack(1) + union { + #pragma pack(1) + struct { + uint8_t bMessageType; /* Offset = 0*/ + uint32_t dwLength; /* Offset = 1, The length field (dwLength) is the length + of the message not including the 10-byte header.*/ + uint8_t bSlot; /* Offset = 5*/ + uint8_t bSeq; /* Offset = 6*/ + uint8_t bSpecific_0; /* Offset = 7*/ + uint8_t bSpecific_1; /* Offset = 8*/ + uint8_t bSpecific_2; /* Offset = 9*/ + } bulkout; + #pragma pack(1) + struct { + uint8_t bMessageType; /* Offset = 0*/ + uint32_t dwLength; /* Offset = 1*/ + uint8_t bSlot; /* Offset = 5, Same as Bulk-OUT message */ + uint8_t bSeq; /* Offset = 6, Same as Bulk-OUT message */ + uint8_t bStatus; /* Offset = 7, Slot status as defined in § 6.2.6*/ + uint8_t bError; /* Offset = 8, Slot error as defined in § 6.2.6*/ + uint8_t bSpecific; /* Offset = 9*/ + } bulkin; + } header; + uint8_t abData [ABDATA_SIZE]; /* Offset = 10, For reference, the absolute + maximum block size for a TPDU T=0 block is 260 bytes + (5 bytes command; 255 bytes data), + or for a TPDU T=1 block is 259 bytes, + or for a short APDU T=1 block is 261 bytes, + or for an extended APDU T=1 block is 65544 bytes.*/ +} Ccid_bulk_data_t; +#pragma pack() + + +#pragma pack() + +typedef struct +{ + __IO uint8_t SlotStatus; + __IO uint8_t SlotStatusChange; +} Ccid_SlotStatus_t; + + +typedef struct +{ + __IO uint8_t bAbortRequestFlag; + __IO uint8_t bSeq; + __IO uint8_t bSlot; +} usb_ccid_param_t; + + +#pragma pack(1) +typedef struct _Protocol0_DataStructure_t +{ + uint8_t bmFindexDindex; + uint8_t bmTCCKST0; + uint8_t bGuardTimeT0; + uint8_t bWaitingIntegerT0; + uint8_t bClockStop; +} Protocol0_DataStructure_t; +#pragma pack() + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ccid_core.h" + +extern usb_ccid_param_t usb_ccid_param; +extern Ccid_bulk_data_t Ccid_bulk_data; /* Buffer for the Out Data */ +extern Ccid_SlotStatus_t Ccid_SlotStatus; +extern uint8_t UsbIntMessageBuffer[]; + +extern Protocol0_DataStructure_t Protocol0_DataStructure; + +/* Exported macros -----------------------------------------------------------*/ +/* Exported variables --------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +void CCID_BulkMessage_In (USBD_HandleTypeDef *pdev, + uint8_t epnum); + +void CCID_BulkMessage_Out (USBD_HandleTypeDef *pdev, + uint8_t epnum, uint8_t* buffer, uint16_t buflen); + +void CCID_ReceiveCmdHeader(uint8_t* pDst, uint8_t u8length); +void CCID_CmdDecode(USBD_HandleTypeDef *pdev); + +void CCID_IntMessage(USBD_HandleTypeDef *pdev); +void CCID_Init(USBD_HandleTypeDef *pdev); +void CCID_DeInit(USBD_HandleTypeDef *pdev); + +uint8_t CCID_IsIntrTransferComplete(void); +void CCID_SetIntrTransferStatus (uint8_t ); +void Transfer_Data_Request(void); +void Set_CSW (uint8_t CSW_Status, uint8_t Send_Permission); + +void io_usb_ccid_set_card_inserted(unsigned int inserted); + +#endif // HAVE_USB_CLASS_CCID + +#endif /* __USBD_CCID_IF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/src/gpg_api.h b/src/gpg_api.h index 378fd01..fa9f854 100644 --- a/src/gpg_api.h +++ b/src/gpg_api.h @@ -16,11 +16,7 @@ #ifndef GPG_API_H #define GPG_API_H -void USBD_CCID_activate_pinpad(int enabled); - -unsigned int gpg_oid2curve(unsigned char* oid, unsigned int len); -unsigned char* gpg_curve2oid(unsigned int cv, unsigned int *len); -unsigned int gpg_curve2domainlen(unsigned int cv); +int gpg_oid2curve(unsigned char* oid, unsigned int len); void gpg_init(void); void gpg_init_ux(void); @@ -32,7 +28,7 @@ int gpg_apdu_get_data(unsigned int ref) ; int gpg_apdu_get_next_data(unsigned int ref) ; int gpg_apdu_put_data(unsigned int ref) ; -int gpg_apdu_pso(void); +int gpg_apdu_pso(unsigned int ref); int gpg_apdu_internal_authenticate(void); int gpg_apdu_gen(void ); int gpg_apdu_get_challenge(void) ; diff --git a/src/gpg_challenge.c b/src/gpg_challenge.c index 7144574..1a655f7 100644 --- a/src/gpg_challenge.c +++ b/src/gpg_challenge.c @@ -44,16 +44,16 @@ int gpg_apdu_get_challenge() { chain[0] = 'r'; chain[1]='n'; chain[2] = 'd'; cx_sha256_init(&G_gpg_vstate.work.md.sha256); - cx_hash((cx_hash_t *)&G_gpg_vstate.work.md.sha256, 0, Sr, 32, NULL, 0); - cx_hash((cx_hash_t *)&G_gpg_vstate.work.md.sha256, 0, chain, 3, NULL, 0); + cx_hash((cx_hash_t *)&G_gpg_vstate.work.md.sha256, 0, Sr, 32, NULL); + cx_hash((cx_hash_t *)&G_gpg_vstate.work.md.sha256, 0, chain, 3, NULL); hlen=cx_hash((cx_hash_t *)&G_gpg_vstate.work.md.sha256, CX_LAST, G_gpg_vstate.work.io_buffer, G_gpg_vstate.io_length, - G_gpg_vstate.work.io_buffer, 32); + G_gpg_vstate.work.io_buffer); cx_sha3_xof_init(&G_gpg_vstate.work.md.sha3, 256, olen); cx_hash((cx_hash_t *)&G_gpg_vstate.work.md.sha3, CX_LAST, G_gpg_vstate.work.io_buffer, hlen, - G_gpg_vstate.work.io_buffer,olen); + G_gpg_vstate.work.io_buffer); } else { cx_rng(G_gpg_vstate.work.io_buffer, olen); } diff --git a/src/gpg_data.c b/src/gpg_data.c index 8273bf9..2c1ac08 100644 --- a/src/gpg_data.c +++ b/src/gpg_data.c @@ -67,7 +67,7 @@ int gpg_apdu_get_data(unsigned int ref) { break; /* ----------------- Config RSA exponent ----------------- */ case 0x01F8: - gpg_io_insert(N_gpg_pstate->default_RSA_exponent,4); + gpg_io_insert_u32(N_gpg_pstate->default_RSA_exponent); break; /* ----------------- Application ----------------- */ @@ -282,7 +282,7 @@ int gpg_apdu_put_data(unsigned int ref) { if (G_gpg_vstate.io_length != 4) { THROW(SW_WRONG_LENGTH); } - G_gpg_vstate.work.io_buffer[G_gpg_vstate.io_offset+3] &= ~0x07; + G_gpg_vstate.work.io_buffer[G_gpg_vstate.io_offset] &= ~0x07; nvm_write(&N_gpg_pstate->AID[10], &G_gpg_vstate.work.io_buffer[G_gpg_vstate.io_offset], 4); break; @@ -367,25 +367,34 @@ int gpg_apdu_put_data(unsigned int ref) { //check length ksz = (keygpg->attributes.value[1]<<8)|keygpg->attributes.value[2]; ksz = ksz >> 3; - rsa_pub = (cx_rsa_public_key_t*)&G_gpg_vstate.work.rsa.public; - rsa_priv = (cx_rsa_private_key_t*)&G_gpg_vstate.work.rsa.private; - pkey = &keygpg->priv_key.rsa; switch(ksz) { case 1024/8: + rsa_pub = (cx_rsa_public_key_t*)&G_gpg_vstate.work.rsa1024.public; + rsa_priv = (cx_rsa_private_key_t*)&G_gpg_vstate.work.rsa1024.private; + pkey = (cx_rsa_private_key_t*)&keygpg->key.rsa1024; pkey_size = sizeof(cx_rsa_1024_private_key_t); - pq = G_gpg_vstate.work.rsa.public1024.n; + pq = G_gpg_vstate.work.rsa1024.public.n; break; case 2048/8: + rsa_pub = (cx_rsa_public_key_t*)&G_gpg_vstate.work.rsa2048.public; + rsa_priv = (cx_rsa_private_key_t*)&G_gpg_vstate.work.rsa2048.private; + pkey = (cx_rsa_private_key_t*)&keygpg->key.rsa2048; pkey_size = sizeof(cx_rsa_2048_private_key_t); - pq = G_gpg_vstate.work.rsa.public2048.n; + pq = G_gpg_vstate.work.rsa2048.public.n; break; case 3072/8: + rsa_pub = (cx_rsa_public_key_t*)&G_gpg_vstate.work.rsa3072.public; + rsa_priv = (cx_rsa_private_key_t*)&G_gpg_vstate.work.rsa3072.private; + pkey = (cx_rsa_private_key_t*)&keygpg->key.rsa3072; pkey_size = sizeof(cx_rsa_3072_private_key_t); - pq = G_gpg_vstate.work.rsa.public3072.n; + pq = G_gpg_vstate.work.rsa3072.public.n; break; case 4096/8: + rsa_pub = (cx_rsa_public_key_t*)&G_gpg_vstate.work.rsa4096.public; + rsa_priv = (cx_rsa_private_key_t*)&G_gpg_vstate.work.rsa4096.private; + pkey = (cx_rsa_private_key_t*)&keygpg->key.rsa4096; pkey_size = sizeof(cx_rsa_4096_private_key_t); - pq = G_gpg_vstate.work.rsa.public4096.n; + pq = G_gpg_vstate.work.rsa4096.public.n; break; } ksz = ksz>>1; @@ -424,12 +433,7 @@ int gpg_apdu_put_data(unsigned int ref) { os_memset(pq+ksz, 0, ksz-len_q); //regenerate RSA private key - unsigned char _e[4]; - _e[0] = e>>24; - _e[1] = e>>16; - _e[2] = e>>8; - _e[3] = e>>0; - cx_rsa_generate_pair(ksz<<1, rsa_pub, rsa_priv, _e, 4, pq); + cx_rsa_generate_pair(ksz<<1, rsa_pub, rsa_priv, e, pq); //write keys nvm_write(&keygpg->pub_key.rsa, rsa_pub->e, 4); @@ -451,14 +455,14 @@ int gpg_apdu_put_data(unsigned int ref) { THROW(SW_WRONG_DATA); return 0; } - ksz = gpg_curve2domainlen(curve); - if (ksz == len_p) { - G_gpg_vstate.work.ecfp.private.curve = curve; - G_gpg_vstate.work.ecfp.private.d_len = ksz; - os_memmove(G_gpg_vstate.work.ecfp.private.d, G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset,ksz); - cx_ecfp_generate_pair(curve, &G_gpg_vstate.work.ecfp.public, &G_gpg_vstate.work.ecfp.private, 1); - nvm_write(&keygpg->pub_key.ecfp, &G_gpg_vstate.work.ecfp.public, sizeof(cx_ecfp_public_key_t)); - nvm_write(&keygpg->priv_key.ecfp, &G_gpg_vstate.work.ecfp.private, sizeof(cx_ecfp_private_key_t)); + ksz = 32; + if (ksz == 32) { + G_gpg_vstate.work.ecfp256.private.curve = curve; + G_gpg_vstate.work.ecfp256.private.d_len = ksz; + os_memmove(G_gpg_vstate.work.ecfp256.private.d, G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset,ksz); + cx_ecfp_generate_pair(curve, &G_gpg_vstate.work.ecfp256.public, &G_gpg_vstate.work.ecfp256.private, 1); + nvm_write(&keygpg->pub_key.ecfp256, &G_gpg_vstate.work.ecfp256.public, sizeof(cx_ecfp_public_key_t)); + nvm_write(&keygpg->key.ecfp256, &G_gpg_vstate.work.ecfp256.private, sizeof(cx_ecfp_private_key_t)); if (reset_cnt) { reset_cnt = 0; nvm_write(&G_gpg_vstate.kslot->sig_count,&reset_cnt,sizeof(unsigned int)); diff --git a/src/gpg_dispatch.c b/src/gpg_dispatch.c index 9640a36..6e907b3 100644 --- a/src/gpg_dispatch.c +++ b/src/gpg_dispatch.c @@ -62,7 +62,7 @@ void gpg_check_access_ins() { case INS_PSO: if ((ref == 0x9e9a) && gpg_pin_is_verified(PIN_ID_PW1)) { - //pso:sign + //pso:sign if (N_gpg_pstate->PW_status[0] == 0) { gpg_pin_set_verified(PIN_ID_PW1, 0); } @@ -236,9 +236,7 @@ int gpg_dispatch() { unsigned int tag,t,l; int sw; - if ((G_gpg_vstate.io_cla != 0x00) && - (G_gpg_vstate.io_cla != 0x10) && - (G_gpg_vstate.io_cla != 0xEF)) { + if ((G_gpg_vstate.io_cla != 0x00) && (G_gpg_vstate.io_cla != 0x10) && (G_gpg_vstate.io_cla != 0xEF)) { THROW(SW_CLA_NOT_SUPPORTED); return SW_CLA_NOT_SUPPORTED; } @@ -380,9 +378,8 @@ int gpg_dispatch() { /* --- PSO --- */ case INS_PSO: - sw = gpg_apdu_pso(); + sw = gpg_apdu_pso(tag); break; - case INS_INTERNAL_AUTHENTICATE: sw = gpg_apdu_internal_authenticate(); break; diff --git a/src/gpg_gen.c b/src/gpg_gen.c index 22564f4..e7de95d 100644 --- a/src/gpg_gen.c +++ b/src/gpg_gen.c @@ -46,12 +46,12 @@ static void gpg_pso_derive_key_seed(unsigned char *Sn, unsigned char* key_name, h[1] = idx; cx_sha256_init(&G_gpg_vstate.work.md.sha256); - cx_hash((cx_hash_t*)&G_gpg_vstate.work.md.sha256, 0, Sn, 32, NULL, 0); - cx_hash((cx_hash_t*)&G_gpg_vstate.work.md.sha256, 0, (unsigned char *)key_name, 4, NULL, 0); - cx_hash((cx_hash_t*)&G_gpg_vstate.work.md.sha256, CX_LAST, h , 2, h,32); + cx_hash((cx_hash_t*)&G_gpg_vstate.work.md.sha256, 0, Sn, 32, NULL); + cx_hash((cx_hash_t*)&G_gpg_vstate.work.md.sha256, 0, (unsigned char *)key_name, 4, NULL); + cx_hash((cx_hash_t*)&G_gpg_vstate.work.md.sha256, CX_LAST, h , 2, h); cx_sha3_xof_init(&G_gpg_vstate.work.md.sha3, 256, Ski_len); - cx_hash((cx_hash_t*)&G_gpg_vstate.work.md.sha3, CX_LAST, h, 32, Ski, Ski_len); + cx_hash((cx_hash_t*)&G_gpg_vstate.work.md.sha3, CX_LAST, h, 32, Ski); } @@ -113,20 +113,29 @@ int gpg_apdu_gen() { ksz = (keygpg->attributes.value[1]<<8)|keygpg->attributes.value[2]; ksz = ksz >> 3; - rsa_pub = (cx_rsa_public_key_t*)&G_gpg_vstate.work.rsa.public; - rsa_priv = (cx_rsa_private_key_t*)&G_gpg_vstate.work.rsa.private; - pkey = &keygpg->priv_key.rsa; switch(ksz) { case 1024/8: + rsa_pub = (cx_rsa_public_key_t*)&G_gpg_vstate.work.rsa1024.public; + rsa_priv = (cx_rsa_private_key_t*)&G_gpg_vstate.work.rsa1024.private; + pkey = (cx_rsa_private_key_t*)&keygpg->key.rsa1024; pkey_size = sizeof(cx_rsa_1024_private_key_t); break; case 2048/8: + rsa_pub = (cx_rsa_public_key_t*)&G_gpg_vstate.work.rsa2048.public; + rsa_priv = (cx_rsa_private_key_t*)&G_gpg_vstate.work.rsa2048.private; + pkey = (cx_rsa_private_key_t*)&keygpg->key.rsa2048; pkey_size = sizeof(cx_rsa_2048_private_key_t); break; case 3072/8: + rsa_pub = (cx_rsa_public_key_t*)&G_gpg_vstate.work.rsa3072.public; + rsa_priv = (cx_rsa_private_key_t*)&G_gpg_vstate.work.rsa3072.private; + pkey = (cx_rsa_private_key_t*)&keygpg->key.rsa3072; pkey_size = sizeof(cx_rsa_3072_private_key_t); break; case 4096/8: + rsa_pub = (cx_rsa_public_key_t*)&G_gpg_vstate.work.rsa4096.public; + rsa_priv = (cx_rsa_private_key_t*)&G_gpg_vstate.work.rsa4096.private; + pkey = (cx_rsa_private_key_t*)&keygpg->key.rsa4096; pkey_size = sizeof(cx_rsa_4096_private_key_t); break; } @@ -144,7 +153,8 @@ int gpg_apdu_gen() { cx_math_next_prime(pq+size,size); } - cx_rsa_generate_pair(ksz, rsa_pub, rsa_priv, N_gpg_pstate->default_RSA_exponent, 4, pq); + + cx_rsa_generate_pair(ksz, rsa_pub, rsa_priv, N_gpg_pstate->default_RSA_exponent, pq); nvm_write(pkey, rsa_priv, pkey_size); nvm_write(&keygpg->pub_key.rsa[0], rsa_pub->e, 4); @@ -164,24 +174,19 @@ int gpg_apdu_gen() { unsigned int curve,keepprivate; keepprivate = 0; curve = gpg_oid2curve(keygpg->attributes.value+1, keygpg->attributes.length-1); - if (curve == CX_CURVE_NONE) { - THROW(SW_REFERENCED_DATA_NOT_FOUND); - return SW_REFERENCED_DATA_NOT_FOUND; - } if ((G_gpg_vstate.io_p2 == 0x01) | (G_gpg_vstate.seed_mode)) { - ksz = gpg_curve2domainlen(curve); gpg_pso_derive_slot_seed(G_gpg_vstate.slot, seed); - gpg_pso_derive_key_seed(seed, name, 1, seed, ksz); - cx_ecfp_init_private_key(curve,seed, ksz, &G_gpg_vstate.work.ecfp.private); + gpg_pso_derive_key_seed(seed, name, 1, seed, 32); + cx_ecfp_init_private_key(curve,seed, 32, &G_gpg_vstate.work.ecfp256.private); keepprivate = 1; } cx_ecfp_generate_pair(curve, - &G_gpg_vstate.work.ecfp.public, - &G_gpg_vstate.work.ecfp.private, + &G_gpg_vstate.work.ecfp256.public, + &G_gpg_vstate.work.ecfp256.private, keepprivate); - nvm_write(&keygpg->priv_key.ecfp, &G_gpg_vstate.work.ecfp.private, sizeof(cx_ecfp_private_key_t)); - nvm_write(&keygpg->pub_key.ecfp, &G_gpg_vstate.work.ecfp.public, sizeof(cx_ecfp_public_key_t)); + nvm_write(&keygpg->key.ecfp256, &G_gpg_vstate.work.ecfp256.private, sizeof(cx_ecfp_private_key_t)); + nvm_write(&keygpg->pub_key.ecfp256, &G_gpg_vstate.work.ecfp256.public, sizeof(cx_ecfp_public_key_t)); if (reset_cnt) { reset_cnt = 0; nvm_write(&G_gpg_vstate.kslot->sig_count,&reset_cnt,sizeof(unsigned int)); @@ -203,32 +208,32 @@ int gpg_apdu_gen() { gpg_io_mark(); switch(ksz) { case 1024/8: - if (keygpg->priv_key.rsa1024.size == 0) { + if (keygpg->key.rsa1024.size == 0) { THROW (SW_REFERENCED_DATA_NOT_FOUND); return SW_REFERENCED_DATA_NOT_FOUND; } - gpg_io_insert_tlv(0x81,ksz,(unsigned char*)&keygpg->priv_key.rsa1024.n); + gpg_io_insert_tlv(0x81,ksz,(unsigned char*)&keygpg->key.rsa1024.n); break; case 2048/8: - if (keygpg->priv_key.rsa2048.size == 0) { + if (keygpg->key.rsa2048.size == 0) { THROW (SW_REFERENCED_DATA_NOT_FOUND); return SW_REFERENCED_DATA_NOT_FOUND; } - gpg_io_insert_tlv(0x81,ksz,(unsigned char*)&keygpg->priv_key.rsa2048.n); + gpg_io_insert_tlv(0x81,ksz,(unsigned char*)&keygpg->key.rsa2048.n); break; case 3072/8: - if (keygpg->priv_key.rsa3072.size == 0) { + if (keygpg->key.rsa3072.size == 0) { THROW (SW_REFERENCED_DATA_NOT_FOUND); return SW_REFERENCED_DATA_NOT_FOUND; } - gpg_io_insert_tlv(0x81,ksz,(unsigned char*)&keygpg->priv_key.rsa3072.n); + gpg_io_insert_tlv(0x81,ksz,(unsigned char*)&keygpg->key.rsa3072.n); break; case 4096/8: - if (keygpg->priv_key.rsa4096.size == 0) { + if (keygpg->key.rsa4096.size == 0) { THROW (SW_REFERENCED_DATA_NOT_FOUND); return SW_REFERENCED_DATA_NOT_FOUND; } - gpg_io_insert_tlv(0x81,ksz,(unsigned char*)&keygpg->priv_key.rsa4096.n); + gpg_io_insert_tlv(0x81,ksz,(unsigned char*)&keygpg->key.rsa4096.n); break; } gpg_io_insert_tlv(0x82, 4, keygpg->pub_key.rsa); @@ -257,7 +262,7 @@ int gpg_apdu_gen() { curve = gpg_oid2curve(keygpg->attributes.value+1, keygpg->attributes.length-1); if (curve == CX_CURVE_Ed25519) { os_memmove(G_gpg_vstate.work.io_buffer+128, keygpg->pub_key.ecfp256.W,keygpg->pub_key.ecfp256.W_len); - cx_edward_compress_point(CX_CURVE_Ed25519, G_gpg_vstate.work.io_buffer+128, 65); + cx_edward_compress_point(CX_CURVE_Ed25519, G_gpg_vstate.work.io_buffer+128); gpg_io_insert_tlv(0x86, 32, G_gpg_vstate.work.io_buffer+129); //129: discard 02 } else if (curve == CX_CURVE_Curve25519) { unsigned int i,len; diff --git a/src/gpg_init.c b/src/gpg_init.c index 07e4d85..03207b1 100644 --- a/src/gpg_init.c +++ b/src/gpg_init.c @@ -18,8 +18,7 @@ #include "gpg_types.h" #include "gpg_api.h" #include "gpg_vars.h" -#include "usbd_impl.h" - +#include "usbd_ccid_impl.h" #define SHORT(x) ((x)>>8)&0xFF, (x)&0xFF /* ----------------------*/ /* -- A Kind of Magic -- */ @@ -32,47 +31,24 @@ const unsigned char C_MAGIC[8] = { /* --ECC OID -- */ /* ----------------------*/ -/* -//brainpool 256t1: 1.3.36.3.3.2.8.1.1.8 -const unsigned char C_OID_BRAINPOOL256T1[9] = { - 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07 -}; -*/ - -//secp256r1 / NIST P256 /ansi-x9.62 : 1.2.840.10045.3.1.7 -const unsigned char C_OID_SECP256R1[8] = { - 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07 -}; -//secp384r1 / NIST P384 /ansi-x9.62 :1.3.132.0.34 -const unsigned char C_OID_SECP384R1[5] = { - 0x2B, 0x81, 0x04, 0x00 , 0x22 -}; -//secp521r1 / NIST P521 /ansi-x9.62 : 1.3.132.0.35 -const unsigned char C_OID_SECP521R1[5] = { - 0x2B, 0x81, 0x04, 0x00, 0x23 -}; - - //secp256k1: 1.3.132.0.10 const unsigned char C_OID_SECP256K1[5] = { 0x2B, 0x81, 0x04, 0x00, 0x0A }; +//secp256r1 / NIST P256 /ansi-x9.62 : 1.2.840.10045.3.1.7 +const unsigned char C_OID_SECP256R1[8] = { + 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07 +}; //brainpool 256r1: 1.3.36.3.3.2.8.1.1.7 const unsigned char C_OID_BRAINPOOL256R1[9] = { - 0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x08 + 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x08 }; -//brainpool 284r1: 1.3.36.3.3.2.8.1.1.11 -const unsigned char C_OID_BRAINPOOL384R1[9] = { - 0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0B +//brainpool 256t1: 1.3.36.3.3.2.8.1.1.8 +const unsigned char C_OID_BRAINPOOL256T1[9] = { + 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07 }; -//brainpool 512r1: 1.3.36.3.3.2.8.1.1.13 -const unsigned char C_OID_BRAINPOOL512R1[9] = { - 0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0D -}; - - //Ed25519/curve25519: 1.3.6.1.4.1.11591.15.1 const unsigned char C_OID_Ed25519[9] = { 0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0F, 0x01, @@ -83,29 +59,10 @@ const unsigned char C_OID_cv25519[10] = { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01, }; -unsigned int gpg_oid2curve(unsigned char* oid, unsigned int len) { - if ( (len == sizeof(C_OID_SECP256K1)) && (os_memcmp(oid, C_OID_SECP256K1, len)==0) ) { - return CX_CURVE_SECP256K1; - } +int gpg_oid2curve(unsigned char* oid, unsigned int len) { if ( (len == sizeof(C_OID_SECP256R1)) && (os_memcmp(oid, C_OID_SECP256R1, len)==0) ) { - return CX_CURVE_SECP256R1; - } - if ( (len == sizeof(C_OID_SECP384R1)) && (os_memcmp(oid, C_OID_SECP384R1, len)==0) ) { - return CX_CURVE_SECP384R1; - } - if ( (len == sizeof(C_OID_SECP521R1)) && (os_memcmp(oid, C_OID_SECP521R1, len)==0) ) { - return CX_CURVE_SECP521R1; - } - - if ( (len == sizeof(C_OID_BRAINPOOL256R1)) && (os_memcmp(oid, C_OID_BRAINPOOL256R1, len)==0) ) { - return CX_CURVE_BrainPoolP256R1; - } - if ( (len == sizeof(C_OID_BRAINPOOL384R1)) && (os_memcmp(oid, C_OID_BRAINPOOL384R1, len)==0) ) { - return CX_CURVE_BrainPoolP384R1; - } - if ( (len == sizeof(C_OID_BRAINPOOL512R1)) && (os_memcmp(oid, C_OID_BRAINPOOL512R1, len)==0) ) { - return CX_CURVE_BrainPoolP512R1; + return CX_CURVE_256R1; } if ( (len == sizeof(C_OID_Ed25519)) && (os_memcmp(oid, C_OID_Ed25519, len)==0) ) { @@ -115,87 +72,21 @@ unsigned int gpg_oid2curve(unsigned char* oid, unsigned int len) { if ( (len == sizeof(C_OID_cv25519)) && (os_memcmp(oid, C_OID_cv25519, len)==0) ) { return CX_CURVE_Curve25519; } - - /* + if ( (len == sizeof(C_OID_SECP256K1)) && (os_memcmp(oid, C_OID_SECP256K1, len)==0) ) { return CX_CURVE_256K1; } + + if ( (len == sizeof(C_OID_BRAINPOOL256R1)) && (os_memcmp(oid, C_OID_BRAINPOOL256R1, len)==0) ) { + return CX_CURVE_BrainPoolP256R1; + } + if ( (len == sizeof(C_OID_BRAINPOOL256T1)) && (os_memcmp(oid, C_OID_BRAINPOOL256T1, len)==0) ) { return CX_CURVE_BrainPoolP256T1; } - */ return CX_CURVE_NONE; } - -unsigned char* gpg_curve2oid(unsigned int cv, unsigned int *len) { - switch (cv) { - - case CX_CURVE_SECP256K1: - *len = sizeof(C_OID_SECP256K1); - return (unsigned char*)PIC(C_OID_SECP256K1); - - case CX_CURVE_SECP256R1: - *len = sizeof(C_OID_SECP256R1); - return (unsigned char*)PIC(C_OID_SECP256R1); - - case CX_CURVE_SECP384R1: - *len = sizeof(C_OID_SECP384R1); - return (unsigned char*)PIC(C_OID_SECP384R1); - - case CX_CURVE_SECP521R1: - *len = sizeof(C_OID_SECP521R1); - return (unsigned char*)PIC(C_OID_SECP521R1); - - case CX_CURVE_BrainPoolP256R1: - *len = sizeof(C_OID_SECP256R1); - return (unsigned char*)PIC(C_OID_SECP256R1); - - case CX_CURVE_BrainPoolP384R1: - *len = sizeof(C_OID_SECP384R1); - return (unsigned char*)PIC(C_OID_SECP384R1); - - case CX_CURVE_BrainPoolP512R1: - *len = sizeof(C_OID_SECP521R1); - return (unsigned char*)PIC(C_OID_SECP521R1); - - case CX_CURVE_Ed25519: - *len = sizeof(C_OID_Ed25519); - return (unsigned char*)PIC(C_OID_Ed25519); - - case CX_CURVE_Curve25519: - *len = sizeof(C_OID_cv25519); - return (unsigned char*)PIC(C_OID_cv25519); - } - - *len = 0; - return NULL; -} - -unsigned int gpg_curve2domainlen(unsigned int cv) { - switch (cv) { - - case CX_CURVE_SECP256K1: - case CX_CURVE_SECP256R1: - case CX_CURVE_BrainPoolP256R1: - case CX_CURVE_Ed25519: - case CX_CURVE_Curve25519: - return 32; - - case CX_CURVE_SECP384R1: - case CX_CURVE_BrainPoolP384R1: - return 48; - - case CX_CURVE_BrainPoolP512R1: - return 64; - - case CX_CURVE_SECP521R1: - return 66; - } - - return 0; -} - /* -------------------------------*/ /* -- Non Mutable Capabilities -- */ /* -------------------------------*/ @@ -231,7 +122,7 @@ const unsigned char C_ext_length[8] = { const unsigned char C_default_AID[] = { 0xD2, 0x76, 0x00, 0x01, 0x24, 0x01, //version - 0x03, 0x03, + 0x03, 0x00, //manufacturer 0x2C, 0x97, //serial @@ -263,7 +154,7 @@ const unsigned char C_default_AlgoAttrRSA[] = { 0x01 }; -#if 0 +#if 1 const unsigned char C_default_AlgoAttrECC_sig[] = { // ecdsa 0x13, @@ -276,20 +167,8 @@ const unsigned char C_default_AlgoAttrECC_dec[] = { // NIST-P256 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07 }; -#elif 0 -const unsigned char C_default_AlgoAttrECC_sig[] = { - // ecdsa - 0x13, - // NIST-P384 - 0x2B, 0x81, 0x04, 0x00 , 0x22 -}; -const unsigned char C_default_AlgoAttrECC_dec[] = { - // ecdh - 0x12, - // NIST-P384 - 0x2B, 0x81, 0x04, 0x00 , 0x22 -}; -#elif 1 + +#else const unsigned char C_default_AlgoAttrECC_sig[] = { // eddsa 0x16, @@ -403,11 +282,8 @@ int gpg_install(unsigned char app_state) { gpg_nvm_write(&N_gpg_pstate->config_slot, G_gpg_vstate.work.io_buffer, 3); //config rsa pub - G_gpg_vstate.work.io_buffer[0] = (GPG_RSA_DEFAULT_PUB>>24)&0xFF; - G_gpg_vstate.work.io_buffer[1] = (GPG_RSA_DEFAULT_PUB>>16)&0xFF; - G_gpg_vstate.work.io_buffer[2] = (GPG_RSA_DEFAULT_PUB>>8)&0xFF; - G_gpg_vstate.work.io_buffer[3] = (GPG_RSA_DEFAULT_PUB>>0)&0xFF; - nvm_write(&N_gpg_pstate->default_RSA_exponent, G_gpg_vstate.work.io_buffer, 4); + l = GPG_RSA_DEFAULT_PUB; + nvm_write(&N_gpg_pstate->default_RSA_exponent, &l, sizeof(unsigned int)); //config pin #if 1 @@ -423,9 +299,6 @@ int gpg_install(unsigned char app_state) { //default key template: RSA 2048) for (int s = 0; s< GPG_KEYS_SLOTS; s++) { - unsigned char uif[2]; - uif[0] = 0x00; - uif[1] = 0x20; #if 1 l = sizeof(C_default_AlgoAttrRSA); gpg_nvm_write(&N_gpg_pstate->keys[s].sig.attributes.value, (void*)C_default_AlgoAttrRSA, l); @@ -444,25 +317,8 @@ int gpg_install(unsigned char app_state) { gpg_nvm_write(&N_gpg_pstate->keys[s].dec.attributes.value, (void*)C_default_AlgoAttrECC_dec, l); gpg_nvm_write(&N_gpg_pstate->keys[s].dec.attributes.length, &l, sizeof(unsigned int)); #endif - gpg_nvm_write(&N_gpg_pstate->keys[s].sig.UIF, &uif, 2); - gpg_nvm_write(&N_gpg_pstate->keys[s].dec.UIF, &uif, 2); - gpg_nvm_write(&N_gpg_pstate->keys[s].aut.UIF, &uif, 2); - - } } return 0; } - - -#define USBD_OFFSET_CfgDesc_bPINSupport (sizeof(USBD_CfgDesc)-16) -void USBD_CCID_activate_pinpad(int enabled) { - unsigned short length; - uint8_t *cfgDesc; - unsigned char e; - e = enabled?3:0; - length = 0; - cfgDesc = USBD_GetCfgDesc_impl(&length); - nvm_write(cfgDesc+(length-16), &e,1); -} diff --git a/src/gpg_io.c b/src/gpg_io.c index 9a36db2..4fa85b1 100644 --- a/src/gpg_io.c +++ b/src/gpg_io.c @@ -149,7 +149,10 @@ void gpg_io_insert_tlv(unsigned int T, unsigned int L, unsigned char const *V) { /* ----------------------------------------------------------------------- */ /* FECTH data from received buffer */ /* ----------------------------------------------------------------------- */ - +void gpg_io_fetch_buffer(unsigned char* buffer, unsigned int len) { + os_memmove(buffer, G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset, len); + G_gpg_vstate.io_offset += len; +} unsigned int gpg_io_fetch_u32() { unsigned int v32; diff --git a/src/gpg_main.c b/src/gpg_main.c index 78bb5e2..9390543 100644 --- a/src/gpg_main.c +++ b/src/gpg_main.c @@ -165,7 +165,7 @@ __attribute__((section(".boot"))) int main(void) { //start communication with MCU io_seproxyhal_init(); - USB_power(1); + USB_CCID_power(1); io_usb_ccid_set_card_inserted(1); diff --git a/src/gpg_pin.c b/src/gpg_pin.c index 4ed7aa2..7def70f 100644 --- a/src/gpg_pin.c +++ b/src/gpg_pin.c @@ -63,7 +63,7 @@ static int gpg_pin_check_internal(gpg_pin_t *pin, unsigned char *pin_val, int p counter = pin->counter-1; gpg_nvm_write(&(pin->counter), &counter, sizeof(int)); cx_sha256_init(&sha256); - cx_hash((cx_hash_t*)&sha256, CX_LAST, pin_val, pin_len, NULL, 0); + cx_hash((cx_hash_t*)&sha256, CX_LAST, pin_val, pin_len, NULL); if (os_memcmp(sha256.acc, pin->value, 32)) { return SW_SECURITY_STATUS_NOT_SATISFIED; } @@ -103,7 +103,7 @@ void gpg_pin_set(gpg_pin_t *pin, unsigned char *pin_val, unsigned int pin_len) { gpg_pin_t newpin; cx_sha256_init(&sha256); - cx_hash((cx_hash_t*)&sha256, CX_LAST, pin_val, pin_len, newpin.value, 32); + cx_hash((cx_hash_t*)&sha256, CX_LAST, pin_val, pin_len, newpin.value); newpin.length = pin_len; newpin.counter = 3; diff --git a/src/gpg_pso.c b/src/gpg_pso.c index 1d389b0..d98b0e1 100644 --- a/src/gpg_pso.c +++ b/src/gpg_pso.c @@ -18,7 +18,6 @@ #include "gpg_types.h" #include "gpg_api.h" #include "gpg_vars.h" -#include "gpg_ux_nanos.h" const unsigned char gpg_oid_sha256[] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 @@ -42,16 +41,16 @@ static int gpg_sign(gpg_key_t *sigkey) { ksz = ksz>>3; switch(ksz) { case 1024/8: - key = (cx_rsa_private_key_t *)&sigkey->priv_key.rsa1024; + key = (cx_rsa_private_key_t *)&sigkey->key.rsa1024; break; case 2048/8: - key = (cx_rsa_private_key_t *)&sigkey->priv_key.rsa2048; + key = (cx_rsa_private_key_t *)&sigkey->key.rsa2048; break; case 3072/8: - key = (cx_rsa_private_key_t *)&sigkey->priv_key.rsa3072; + key = (cx_rsa_private_key_t *)&sigkey->key.rsa3072; break; case 4096/8: - key = (cx_rsa_private_key_t *)&sigkey->priv_key.rsa4096; + key = (cx_rsa_private_key_t *)&sigkey->key.rsa4096; break; } if (key->size != ksz) { @@ -87,27 +86,23 @@ static int gpg_sign(gpg_key_t *sigkey) { unsigned int sz,i,rs_len; unsigned char *rs; - key = &sigkey->priv_key.ecfp; - + key = &sigkey->key.ecfp256; + if (key->d_len != 32) { + THROW(SW_CONDITIONS_NOT_SATISFIED); + return SW_CONDITIONS_NOT_SATISFIED; + } //sign - #define RS (G_gpg_vstate.work.io_buffer+(GPG_IO_BUFFER_LENGTH-256)) if (sigkey->attributes.value[0] == 19) { - sz = gpg_curve2domainlen(key->curve); - if ((sz == 0) || (key->d_len != sz)) { - THROW(SW_CONDITIONS_NOT_SATISFIED); - return SW_CONDITIONS_NOT_SATISFIED; - } sz = cx_ecdsa_sign(key, CX_RND_TRNG, CX_NONE, - G_gpg_vstate.work.io_buffer, sz, - RS, 256, - NULL); + G_gpg_vstate.work.io_buffer, G_gpg_vstate.io_length, + G_gpg_vstate.work.io_buffer); //reencode r,s in MPI format gpg_io_discard(0); - rs_len = RS[3]; - rs = &RS[4]; + rs_len = G_gpg_vstate.work.io_buffer[3]; + rs = &G_gpg_vstate.work.io_buffer[4]; for (i = 0; i<2; i++) { if (*rs == 0) { @@ -121,18 +116,15 @@ static int gpg_sign(gpg_key_t *sigkey) { rs += 2; } } else{ - sz = cx_eddsa_sign(key, + sz = cx_eddsa_sign(key, NULL, CX_NONE, - CX_SHA512, + CX_SHA512, G_gpg_vstate.work.io_buffer, G_gpg_vstate.io_length, - NULL, 0, - RS, 256, - NULL); + G_gpg_vstate.work.io_buffer+128); gpg_io_discard(0); - gpg_io_insert(RS, sz); + gpg_io_insert(G_gpg_vstate.work.io_buffer+128, sz); } - #undef RS - + //send gpg_pso_reset_PW1(); return SW_OK; @@ -142,38 +134,8 @@ static int gpg_sign(gpg_key_t *sigkey) { return SW_REFERENCED_DATA_NOT_FOUND; } -int gpg_apdu_pso() { +int gpg_apdu_pso(unsigned int pso) { unsigned int t,l,ksz; - - unsigned int pso; - - pso = (G_gpg_vstate.io_p1 << 8) | G_gpg_vstate.io_p2 ; - - //UIF HANDLE - switch(pso) { - // --- PSO:CDS --- - case 0x9e9a: - if (G_gpg_vstate.kslot->sig.UIF[0]) { - if ((G_gpg_vstate.UIF_flags)==0) { - ui_menu_uifconfirm_display(0); - return 0; - } - G_gpg_vstate.UIF_flags = 0; - } - break; - // --- PSO:DEC --- - case 0x8096: - if (G_gpg_vstate.kslot->dec.UIF[0]) { - if ((G_gpg_vstate.UIF_flags)==0) { - ui_menu_uifconfirm_display(0); - return 0; - } - G_gpg_vstate.UIF_flags = 0; - } - break; - } - - // --- PSO:ENC --- switch(pso) { // --- PSO:CDS --- case 0x9e9a: { @@ -198,7 +160,7 @@ int gpg_apdu_pso() { sz = cx_aes(key, CX_ENCRYPT|CX_CHAIN_CBC|CX_LAST, G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset, msg_len, - G_gpg_vstate.work.io_buffer+1, GPG_IO_BUFFER_LENGTH-1); + G_gpg_vstate.work.io_buffer+1); //send gpg_io_discard(0); G_gpg_vstate.work.io_buffer[0] = 0x02; @@ -226,16 +188,16 @@ int gpg_apdu_pso() { key = NULL; switch(ksz) { case 1024/8: - key = (cx_rsa_private_key_t *)&G_gpg_vstate.mse_dec->priv_key.rsa1024; + key = (cx_rsa_private_key_t *)&G_gpg_vstate.mse_dec->key.rsa1024; break; case 2048/8: - key = (cx_rsa_private_key_t *)&G_gpg_vstate.mse_dec->priv_key.rsa2048; + key = (cx_rsa_private_key_t *)&G_gpg_vstate.mse_dec->key.rsa2048; break; case 3072/8: - key = (cx_rsa_private_key_t *)&G_gpg_vstate.mse_dec->priv_key.rsa3072; + key = (cx_rsa_private_key_t *)&G_gpg_vstate.mse_dec->key.rsa3072; break; case 4096/8: - key = (cx_rsa_private_key_t *)&G_gpg_vstate.mse_dec->priv_key.rsa4096; + key = (cx_rsa_private_key_t *)&G_gpg_vstate.mse_dec->key.rsa4096; break; } @@ -268,7 +230,7 @@ int gpg_apdu_pso() { sz = cx_aes(key, CX_DECRYPT|CX_CHAIN_CBC|CX_LAST, G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset, msg_len, - G_gpg_vstate.work.io_buffer, GPG_IO_BUFFER_LENGTH); + G_gpg_vstate.work.io_buffer); //send gpg_io_discard(0); gpg_io_inserted(sz); @@ -284,7 +246,11 @@ int gpg_apdu_pso() { THROW(SW_CONDITIONS_NOT_SATISFIED); return SW_CONDITIONS_NOT_SATISFIED; } - key = &G_gpg_vstate.mse_dec->priv_key.ecfp; + key = &G_gpg_vstate.mse_dec->key.ecfp256; + if (key->d_len != 32) { + THROW(SW_CONDITIONS_NOT_SATISFIED); + return SW_CONDITIONS_NOT_SATISFIED; + } gpg_io_fetch_l(&l); gpg_io_fetch_tl(&t, &l); if (t != 0x7f49) { @@ -298,10 +264,6 @@ int gpg_apdu_pso() { } curve = gpg_oid2curve(G_gpg_vstate.mse_dec->attributes.value+1, G_gpg_vstate.mse_dec->attributes.length-1); - if (key->curve != curve) { - THROW(SW_CONDITIONS_NOT_SATISFIED); - return SW_CONDITIONS_NOT_SATISFIED; - } if (curve == CX_CURVE_Curve25519) { unsigned int i; @@ -311,8 +273,8 @@ int gpg_apdu_pso() { G_gpg_vstate.work.io_buffer[511] = 0x02; sz = cx_ecdh(key, CX_ECDH_X, - G_gpg_vstate.work.io_buffer+511, 65, - G_gpg_vstate.work.io_buffer+256, 160); + G_gpg_vstate.work.io_buffer+511, + G_gpg_vstate.work.io_buffer+256); for (i = 0; i <=31; i++) { G_gpg_vstate.work.io_buffer[128+i] = G_gpg_vstate.work.io_buffer[287-i]; } @@ -320,8 +282,8 @@ int gpg_apdu_pso() { } else { sz = cx_ecdh(key, CX_ECDH_X, - G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset, 65, - G_gpg_vstate.work.io_buffer+128, 160); + G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset, + G_gpg_vstate.work.io_buffer+128); } //send gpg_io_discard(0); @@ -334,6 +296,7 @@ int gpg_apdu_pso() { THROW(SW_REFERENCED_DATA_NOT_FOUND); return SW_REFERENCED_DATA_NOT_FOUND; } + } //--- PSO:yy NOT SUPPPORTED --- @@ -347,15 +310,6 @@ int gpg_apdu_pso() { int gpg_apdu_internal_authenticate() { - // --- PSO:AUTH --- - if (G_gpg_vstate.kslot->aut.UIF[0]) { - if ((G_gpg_vstate.UIF_flags)==0) { - ui_menu_uifconfirm_display(0); - return 0; - } - G_gpg_vstate.UIF_flags = 0; - } - if (G_gpg_vstate.mse_aut->attributes.value[0] == 1) { if ( G_gpg_vstate.io_length > ((G_gpg_vstate.mse_aut->attributes.value[1]<<8)|G_gpg_vstate.mse_aut->attributes.value[2])*40/100) { THROW(SW_WRONG_LENGTH); diff --git a/src/gpg_select.c b/src/gpg_select.c index 6c36ac5..908f874 100644 --- a/src/gpg_select.c +++ b/src/gpg_select.c @@ -19,19 +19,10 @@ #include "gpg_types.h" #include "gpg_api.h" #include "gpg_vars.h" -const unsigned char C_MF[] = {0x3F, 0x00}; int gpg_apdu_select() { int sw; - - //MF - if ( (G_gpg_vstate.io_length == 2) && - (os_memcmp(G_gpg_vstate.work.io_buffer, C_MF, G_gpg_vstate.io_length) == 0) ) { - gpg_io_discard(0); - sw = SW_OK; - } - //AID APP - else if ( (G_gpg_vstate.io_length == 6) && + if ( (G_gpg_vstate.io_length == 6) && (os_memcmp(G_gpg_vstate.work.io_buffer, N_gpg_pstate->AID, G_gpg_vstate.io_length) == 0) ) { G_gpg_vstate.DO_current = 0; G_gpg_vstate.DO_reccord = 0; @@ -49,9 +40,7 @@ int gpg_apdu_select() { THROW(SW_STATE_TERMINATED); } sw = SW_OK; - } - //NOT FOUND - else { + } else { THROW(SW_FILE_NOT_FOUND); return SW_FILE_NOT_FOUND; } diff --git a/src/gpg_types.h b/src/gpg_types.h index c98b766..9b89fc8 100644 --- a/src/gpg_types.h +++ b/src/gpg_types.h @@ -36,7 +36,7 @@ #define GPG_KEY_ATTRIBUTES_LENGTH 12 -#define GPG_RSA_DEFAULT_PUB 0x00010001U +#define GPG_RSA_DEFAULT_PUB 0x010001U struct gpg_pin_s { unsigned int ref; @@ -66,25 +66,15 @@ typedef struct gpg_key_s { LV(attributes,GPG_KEY_ATTRIBUTES_LENGTH); /* key value */ union { - cx_rsa_private_key_t rsa; cx_rsa_1024_private_key_t rsa1024; cx_rsa_2048_private_key_t rsa2048; cx_rsa_3072_private_key_t rsa3072; cx_rsa_4096_private_key_t rsa4096; - - cx_ecfp_private_key_t ecfp; - cx_ecfp_256_private_key_t ecfp256; - cx_ecfp_384_private_key_t ecfp384; - cx_ecfp_512_private_key_t ecfp512; - cx_ecfp_640_private_key_t ecfp640; - } priv_key; + cx_ecfp_private_key_t ecfp256; + } key; union { - unsigned char rsa[4]; - cx_ecfp_public_key_t ecfp; - cx_ecfp_256_public_key_t ecfp256; - cx_ecfp_384_public_key_t ecfp384; - cx_ecfp_512_public_key_t ecfp512; - cx_ecfp_640_public_key_t ecfp640; + unsigned char rsa[4]; + cx_ecfp_public_key_t ecfp256; } pub_key; /* C7 C8 C9 , C5 = C7|C8|C9*/ unsigned char fingerprints[20]; @@ -126,7 +116,7 @@ struct gpg_nv_state_s { /* 01F1 (01F2 is volatile)*/ unsigned char config_slot[3]; /* RSA exponent */ - unsigned char default_RSA_exponent[4]; + unsigned int default_RSA_exponent; /* 0101 0102 0103 0104 */ LV(private_DO1, GPG_EXT_PRIVATE_DO_LENGTH); @@ -188,8 +178,6 @@ struct gpg_v_state_s { gpg_key_t *mse_dec; unsigned char seed_mode; - unsigned char UIF_flags; - /* io state*/ unsigned char io_cla; @@ -203,41 +191,26 @@ struct gpg_v_state_s { unsigned short io_mark; union { unsigned char io_buffer[GPG_IO_BUFFER_LENGTH]; - struct { - union { - cx_rsa_public_key_t public; - cx_rsa_1024_public_key_t public1024; - cx_rsa_2048_public_key_t public2048; - cx_rsa_3072_public_key_t public3072; - cx_rsa_4096_public_key_t public4096; - }; - union { - cx_rsa_private_key_t private; - cx_rsa_1024_private_key_t private1024; - cx_rsa_2048_private_key_t private2048; - cx_rsa_3072_private_key_t private3072; - cx_rsa_4096_private_key_t private4096; - }; - } rsa; - + cx_rsa_1024_public_key_t public; + cx_rsa_1024_private_key_t private; + }rsa1024; struct { - union{ - cx_ecfp_public_key_t public; - cx_ecfp_256_public_key_t public256; - cx_ecfp_384_public_key_t public384; - cx_ecfp_512_public_key_t public512; - cx_ecfp_640_public_key_t public640; - }; - union { - cx_ecfp_private_key_t private; - cx_ecfp_256_private_key_t private256; - cx_ecfp_384_private_key_t private384; - cx_ecfp_512_private_key_t private512; - cx_ecfp_640_private_key_t private640; - }; - }ecfp; - + cx_rsa_2048_public_key_t public; + cx_rsa_2048_private_key_t private; + }rsa2048; + struct { + cx_rsa_3072_public_key_t public; + cx_rsa_3072_private_key_t private; + }rsa3072; + struct { + cx_rsa_4096_public_key_t public; + cx_rsa_4096_private_key_t private; + }rsa4096; + struct { + cx_ecfp_public_key_t public; + cx_ecfp_private_key_t private; + }ecfp256; struct { unsigned char md_buffer[GPG_IO_BUFFER_LENGTH-MAX(sizeof(cx_sha3_t),sizeof(cx_sha256_t))]; union { @@ -257,7 +230,7 @@ struct gpg_v_state_s { unsigned char pinmode; /* ux menus */ - char menu[112]; + char menu[64]; unsigned char ux_pinentry[12]; unsigned int ux_key; unsigned int ux_type; diff --git a/src/gpg_ux_msg.c b/src/gpg_ux_msg.c index c684890..e455438 100644 --- a/src/gpg_ux_msg.c +++ b/src/gpg_ux_msg.c @@ -34,5 +34,3 @@ const char * const C_NOT_ALLOWED = "Not Allowed "; const char * const C_DEFAULT_MODE = "Default mode"; - -const char * const C_UIF_LOCKED = "UIF locked"; diff --git a/src/gpg_ux_msg.h b/src/gpg_ux_msg.h index 38847a6..1090930 100644 --- a/src/gpg_ux_msg.h +++ b/src/gpg_ux_msg.h @@ -36,9 +36,6 @@ extern const char * const C_NOT_ALLOWED; extern const char * const C_DEFAULT_MODE; -extern const char * const C_UIF_LOCKED; -extern const char * const C_UIF_INVALID; - #define PICSTR(x) ((char*)PIC(x)) #define TEMPLATE_TYPE PICSTR(C_TEMPLATE_TYPE) @@ -57,7 +54,5 @@ extern const char * const C_UIF_INVALID; #define ALLOWED PICSTR(C_ALLOWED) #define NOT_ALLOWED PICSTR(C_NOT_ALLOWED) #define DEFAULT_MODE PICSTR(C_DEFAULT_MODE) -#define UIF_LOCKED PICSTR(C_UIF_LOCKED) -#define UIF_INVALID PICSTR(C_UIF_INVALID) #endif diff --git a/src/gpg_ux_nanos.c b/src/gpg_ux_nanos.c index d9e1808..25721e7 100644 --- a/src/gpg_ux_nanos.c +++ b/src/gpg_ux_nanos.c @@ -91,122 +91,6 @@ void ui_info(const char* msg1, const char* msg2, const void *menu_display, unsig UX_MENU_DISPLAY(0, G_gpg_vstate.ui_dogsays, NULL); }; - -/* ------------------------------ UIF CONFIRM UX ----------------------------- */ -unsigned int ui_uifconfirm_nanos_button(unsigned int button_mask, unsigned int button_mask_counter); -unsigned int ui_uifconfirm_prepro(const bagl_element_t* element); - -const bagl_element_t ui_uifconfirm_nanos[] = { - // type userid x y w h str rad fill fg bg font_id icon_id - { {BAGL_RECTANGLE, 0x00, 0, 0, 128, 32, 0, 0, BAGL_FILL, 0x000000, 0xFFFFFF, 0, 0}, - NULL, - 0, - 0, 0, - NULL, NULL, NULL}, - - { {BAGL_ICON, 0x00, 3, 12, 7, 7, 0, 0, 0, 0xFFFFFF, 0x000000, 0, BAGL_GLYPH_ICON_CROSS }, - NULL, - 0, - 0, 0, - NULL, NULL, NULL }, - - { {BAGL_ICON, 0x00, 117, 13, 8, 6, 0, 0, 0, 0xFFFFFF, 0x000000, 0, BAGL_GLYPH_ICON_CHECK }, - NULL, - 0, - 0, 0, - NULL, NULL, NULL }, - - { {BAGL_LABELINE, 0x01, 0, 12, 128, 32, 0, 0, 0, 0xFFFFFF, 0x000000, BAGL_FONT_OPEN_SANS_EXTRABOLD_11px|BAGL_FONT_ALIGNMENT_CENTER, 0 }, - G_gpg_vstate.menu, - 0, - 0, 0, - NULL, NULL, NULL }, - { {BAGL_LABELINE, 0x02, 0, 26, 128, 32, 0, 0, 0, 0xFFFFFF, 0x000000, BAGL_FONT_OPEN_SANS_EXTRABOLD_11px|BAGL_FONT_ALIGNMENT_CENTER, 0 }, - G_gpg_vstate.menu, - 0, - 0, 0, - NULL, NULL, NULL }, -}; - -void ui_menu_uifconfirm_display(unsigned int value) { - UX_DISPLAY(ui_uifconfirm_nanos, (void*)ui_uifconfirm_prepro); -} - -unsigned int ui_uifconfirm_prepro(const bagl_element_t* element) { - if (element->component.userid == 1) { - snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu), "Confirm:"); - return 1; - } - if (element->component.userid == 2) { - unsigned int uif_case = (G_gpg_vstate.io_ins<<16)|(G_gpg_vstate.io_p1<<8)|(G_gpg_vstate.io_p2); - switch (uif_case) { - case 0x002A9E9A: - snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu), "Signature"); - return 1; - case 0x002A8680: - snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu), "Encryption"); - return 1; - case 0x002A8086: - snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu), "Decryption"); - return 1; - case 0x0088000: - snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu), "Authentication"); - return 1; - } - } - snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu), "Please Cancel"); - return 1; -} - -unsigned int ui_uifconfirm_nanos_button(unsigned int button_mask, unsigned int button_mask_counter) { - unsigned int sw; - - sw = 0x6985; - switch(button_mask) { - case BUTTON_EVT_RELEASED|BUTTON_LEFT: // CANCEL - gpg_io_discard(1); - gpg_io_insert_u16(sw); - gpg_io_do(IO_RETURN_AFTER_TX); - ui_menu_main_display(0); - sw = 0x6985; - break; - - case BUTTON_EVT_RELEASED|BUTTON_RIGHT: // OK - BEGIN_TRY { - TRY { - G_gpg_vstate.UIF_flags = 1; - if (G_gpg_vstate.io_ins == INS_PSO) { - sw = gpg_apdu_pso(); - } else if (G_gpg_vstate.io_ins == INS_INTERNAL_AUTHENTICATE) { - sw = gpg_apdu_internal_authenticate(); - } else { - gpg_io_discard(1); - sw = 0x6985; - } - } - CATCH_OTHER(e) { - gpg_io_discard(1); - if ( (e & 0xFFFF0000) || - ( ((e&0xF000)!=0x6000) && ((e&0xF000)!=0x9000) ) ) { - gpg_io_insert_u32(e); - sw = 0x6f42; - } else { - sw = e; - } - } - FINALLY { - G_gpg_vstate.UIF_flags = 0; - gpg_io_insert_u16(sw); - gpg_io_do(IO_RETURN_AFTER_TX); - ui_menu_main_display(0); - } - break; - - } END_TRY; - } - return 0; -} - /* ------------------------------ PIN CONFIRM UX ----------------------------- */ const bagl_element_t ui_pinconfirm_nanos[] = { @@ -506,17 +390,12 @@ static unsigned int validate_pin() { #define LABEL_AUT "Authentication" #define LABEL_DEC "Decryption" -#define LABEL_RSA2048 "RSA 2048" -#define LABEL_RSA3072 "RSA 3072" -#define LABEL_RSA4096 "RSA 4096" -#define LABEL_NISTP256 "NIST P256" -//#define LABEL_NISTP384 "NIST P384" -//#define LABEL_NISTP521 "NIST P521" -#define LABEL_SECP256K1 "SEPC 256K1" -#define LABEL_BPOOL256R1 "Brainpool 256R1" -//#define LABEL_BPOOL384R1 "Brainpool 384R1" -//#define LABEL_BPOOL512R1 "Brainpool 512R1" -#define LABEL_Ed25519 "Ed25519" +#define LABEL_RSA2048 "RSA 2048" +#define LABEL_RSA3072 "RSA 3072" +#define LABEL_RSA4096 "RSA 4096" +#define LABEL_NISTP256 "NIST P256" +#define LABEL_BPOOLR1 "Brainpool R1" +#define LABEL_Ed25519 "Ed25519" const ux_menu_entry_t ui_menu_template[] = { {ui_menu_tmpl_key, NULL, -1, NULL, "Choose key...", NULL, 0, 0}, @@ -560,34 +439,12 @@ const bagl_element_t* ui_menu_template_preprocessor(const ux_menu_entry_t* entry case 4096: snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu)," %s", LABEL_RSA4096); break; - case CX_CURVE_SECP256R1: snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu)," %s", LABEL_NISTP256); break; - /* - case CX_CURVE_SECP384R1: - snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu)," %s", LABEL_NISTP384); - break; - case CX_CURVE_SECP521R1: - snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu)," %s", LABEL_NISTP521); - break; - */ - case CX_CURVE_SECP256K1: - snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu)," %s", LABEL_SECP256K1); - break; - case CX_CURVE_BrainPoolP256R1: - snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu)," %s", LABEL_BPOOL256R1); + snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu)," %s", LABEL_BPOOLR1); break; - /* - case CX_CURVE_BrainPoolP384R1: - snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu)," %s", LABEL_BPOOL384R1); - break; - case CX_CURVE_BrainPoolP512R1: - snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu)," %s", LABEL_BPOOL512R1); - break; - */ - case CX_CURVE_Ed25519: snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu)," %s", LABEL_Ed25519); break; @@ -608,8 +465,7 @@ void ui_menu_tmpl_set_action(unsigned int value) { LV(attributes,GPG_KEY_ATTRIBUTES_LENGTH); gpg_key_t* dest; const char* err; - const unsigned char *oid; - unsigned int oid_len; + err = NULL; os_memset(&attributes, 0, sizeof(attributes)); @@ -626,21 +482,24 @@ void ui_menu_tmpl_set_action(unsigned int value) { attributes.length = 6; break; - case CX_CURVE_SECP256K1: case CX_CURVE_SECP256R1: - //case CX_CURVE_SECP384R1: - //case CX_CURVE_SECP521R1: + if (G_gpg_vstate.ux_key == 2) { + attributes.value[0] = 18; //ecdh + } else { + attributes.value[0] = 19; //ecdsa + } + os_memmove(attributes.value+1, C_OID_SECP256R1, sizeof(C_OID_SECP256R1)); + attributes.length = 1+sizeof(C_OID_SECP256R1); + break; + case CX_CURVE_BrainPoolP256R1: - //case CX_CURVE_BrainPoolP384R1: - //case CX_CURVE_BrainPoolP512R1: - if (G_gpg_vstate.ux_key == 2) { + if (G_gpg_vstate.ux_key == 2) { attributes.value[0] = 18; //ecdh } else { attributes.value[0] = 19; //ecdsa } - oid = gpg_curve2oid(G_gpg_vstate.ux_type, &oid_len); - os_memmove(attributes.value+1, oid, sizeof(oid_len)); - attributes.length = 1+oid_len; + os_memmove(attributes.value+1, C_OID_BRAINPOOL256R1, sizeof(C_OID_BRAINPOOL256R1)); + attributes.length = 1+sizeof(C_OID_BRAINPOOL256R1); break; case CX_CURVE_Ed25519: @@ -655,7 +514,7 @@ void ui_menu_tmpl_set_action(unsigned int value) { } break; - default: + default: err = TEMPLATE_TYPE; goto ERROR; } @@ -702,18 +561,13 @@ void ui_menu_tmpl_key_action(unsigned int value) { const ux_menu_entry_t ui_menu_tmpl_type[] = { - {NULL, ui_menu_tmpl_type_action, 2048, NULL, LABEL_RSA2048, NULL, 0, 0}, - {NULL, ui_menu_tmpl_type_action, 3072, NULL, LABEL_RSA3072, NULL, 0, 0}, - {NULL, ui_menu_tmpl_type_action, 4096, NULL, LABEL_RSA4096, NULL, 0, 0}, - {NULL, ui_menu_tmpl_type_action, CX_CURVE_SECP256R1, NULL, LABEL_NISTP256, NULL, 0, 0}, -// {NULL, ui_menu_tmpl_type_action, CX_CURVE_SECP384R1, NULL, LABEL_NISTP384, NULL, 0, 0}, -// {NULL, ui_menu_tmpl_type_action, CX_CURVE_SECP521R1, NULL, LABEL_NISTP521, NULL, 0, 0}, - {NULL, ui_menu_tmpl_type_action, CX_CURVE_SECP256K1, NULL, LABEL_SECP256K1, NULL, 0, 0}, - {NULL, ui_menu_tmpl_type_action, CX_CURVE_BrainPoolP256R1, NULL, LABEL_BPOOL256R1, NULL, 0, 0}, -// {NULL, ui_menu_tmpl_type_action, CX_CURVE_BrainPoolP384R1, NULL, LABEL_BPOOL384R1, NULL, 0, 0}, -// {NULL, ui_menu_tmpl_type_action, CX_CURVE_BrainPoolP512R1, NULL, LABEL_BPOOL512R1, NULL, 0, 0}, - {NULL, ui_menu_tmpl_type_action, CX_CURVE_Ed25519, NULL, LABEL_Ed25519, NULL, 0, 0}, - {ui_menu_template, NULL, 1, &C_badge_back, "Back", NULL, 61, 40}, + {NULL, ui_menu_tmpl_type_action, 2048, NULL, LABEL_RSA2048, NULL, 0, 0}, + {NULL, ui_menu_tmpl_type_action, 3072, NULL, LABEL_RSA3072, NULL, 0, 0}, + {NULL, ui_menu_tmpl_type_action, 4096, NULL, LABEL_RSA4096, NULL, 0, 0}, + {NULL, ui_menu_tmpl_type_action, CX_CURVE_SECP256R1, NULL, LABEL_NISTP256, NULL, 0, 0}, + {NULL, ui_menu_tmpl_type_action, CX_CURVE_BrainPoolP256R1, NULL, LABEL_BPOOLR1, NULL, 0, 0}, + {NULL, ui_menu_tmpl_type_action, CX_CURVE_Ed25519, NULL, LABEL_Ed25519, NULL, 0, 0}, + {ui_menu_template, NULL, 1, &C_badge_back, "Back", NULL, 61, 40}, UX_MENU_END }; @@ -809,7 +663,6 @@ void ui_menu_pinmode_action(unsigned int value) { } else { s = 3; } - //#warning USBD_CCID_activate_pinpad commented USBD_CCID_activate_pinpad(s); } } @@ -840,84 +693,6 @@ void ui_menu_pinmode_action(unsigned int value) { // redisplay first entry of the idle menu ui_menu_pinmode_display(0); } - - - -/* ------------------------------- UIF MODE UX ------------------------------ */ -const ux_menu_entry_t ui_menu_uifmode[]; -void ui_menu_uifmode_display(unsigned int value); -const bagl_element_t* ui_menu_uifmode_preprocessor(const ux_menu_entry_t* entry, bagl_element_t* element); -void ui_menu_uifmode_action(unsigned int value); - -const ux_menu_entry_t ui_menu_uifmode[] = { - {NULL, NULL, -1, NULL, "Activate (+) for:", NULL, 0, 0}, - {NULL, ui_menu_uifmode_action, 1, NULL, "Signature", NULL, 0, 0}, - {NULL, ui_menu_uifmode_action, 2, NULL, "Decryption", NULL, 0, 0}, - {NULL, ui_menu_uifmode_action, 3, NULL, "Authentication", NULL, 0, 0}, - {ui_menu_settings, NULL, 1, &C_badge_back, "Back", NULL, 61, 40}, - UX_MENU_END -}; - -void ui_menu_uifmode_display(unsigned int value) { - UX_MENU_DISPLAY(value, ui_menu_uifmode, ui_menu_uifmode_preprocessor); -} - -const bagl_element_t* ui_menu_uifmode_preprocessor(const ux_menu_entry_t* entry, bagl_element_t* element) { - if (element->component.userid==0x20) { - if ((entry->userid >= 1) && (entry->userid<=3)) { - unsigned char uif[2] ; - uif[0] = 0; - uif[1] = 0; - switch (entry->userid) { - case 1: - *uif = G_gpg_vstate.kslot->sig.UIF[0]?'+':' '; - break; - case 2: - *uif = G_gpg_vstate.kslot->dec.UIF[0]?'+':' '; - break; - case 3: - *uif = G_gpg_vstate.kslot->aut.UIF[0]?'+':' '; - break; - } - snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu), "%s %s", - (char*)PIC(entry->line1), uif); - element->text = G_gpg_vstate.menu; - element->component.height = 32; - } - } - return element; -} - -void ui_menu_uifmode_action(unsigned int value) { - unsigned char *uif; - unsigned char new_uif; - switch (value) { - case 1: - uif = &G_gpg_vstate.kslot->sig.UIF[0]; - break; - case 2: - uif = &G_gpg_vstate.kslot->dec.UIF[0]; - break; - case 3: - uif = &G_gpg_vstate.kslot->aut.UIF[0]; - break; - default: - ui_info(INVALID_SELECTION, NULL, ui_menu_uifmode_display,0); - return; - } - if (uif[0] == 0) { - new_uif = 1; - gpg_nvm_write(&uif[0], &new_uif, 1); - } else if (uif[0] == 1) { - new_uif = 0; - gpg_nvm_write(&uif[0], &new_uif, 1) ; - } else /*if (uif[0] == 2 )*/ { - ui_info(UIF_LOCKED, NULL, ui_menu_uifmode_display,0); - return; - } - ui_menu_uifmode_display(value); -} - /* -------------------------------- RESET UX --------------------------------- */ const ux_menu_entry_t ui_menu_reset[] = { @@ -944,7 +719,6 @@ const ux_menu_entry_t ui_menu_settings[] = { {NULL, ui_menu_template_display, 0, NULL, "Key template", NULL, 0, 0}, {NULL, ui_menu_seed_display, 0, NULL, "Seed mode", NULL, 0, 0}, {NULL, ui_menu_pinmode_display, 0, NULL, "PIN mode", NULL, 0, 0}, - {NULL, ui_menu_uifmode_display, 0, NULL, "UIF mode", NULL, 0, 0}, {ui_menu_reset, NULL, 0, NULL, "Reset", NULL, 0, 0}, {NULL, ui_menu_main_display, 2, &C_badge_back, "Back", NULL, 61, 40}, UX_MENU_END diff --git a/src/gpg_ux_nanos.h b/src/gpg_ux_nanos.h index ba41bf4..499c86b 100644 --- a/src/gpg_ux_nanos.h +++ b/src/gpg_ux_nanos.h @@ -22,5 +22,4 @@ void ui_init(void); void ui_main_display(unsigned int value); void ui_menu_pinconfirm_display(unsigned int value); void ui_menu_pinentry_display(unsigned int value); -void ui_menu_uifconfirm_display(unsigned int value); #endif \ No newline at end of file diff --git a/src/sdk/usbd_ccid_cmd.c b/src/sdk/usbd_ccid_cmd.c deleted file mode 100755 index 1558d3d..0000000 --- a/src/sdk/usbd_ccid_cmd.c +++ /dev/null @@ -1,1057 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_ccid_cmd.c - * @author MCD Application Team - * @version V1.0.1 - * @date 31-January-2014 - * @brief CCID Commands handling - ****************************************************************************** - * @attention - * - *

© COPYRIGHT 2014 STMicroelectronics

- * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ - -#pragma message "Override SDK source file :" __FILE__ - - -/* Includes ------------------------------------------------------------------*/ -#include "usbd_ccid_cmd.h" - -#ifdef HAVE_USB_CLASS_CCID - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -#define CCID_UpdateCommandStatus(cmd_status,icc_status)\ - G_io_ccid.bulk_header.bulkin.bStatus=(cmd_status|icc_status) - /* - The Above Macro can take any of following Values - #define BM_ICC_PRESENT_ACTIVE 0x00 - #define BM_ICC_PRESENT_INACTIVE 0x01 - #define BM_ICC_NO_ICC_PRESENT 0x02 - - #define BM_COMMAND_STATUS_OFFSET 0x06 - #define BM_COMMAND_STATUS_NO_ERROR 0x00 - #define BM_COMMAND_STATUS_FAILED (0x01 << BM_COMMAND_STATUS_OFFSET) - #define BM_COMMAND_STATUS_TIME_EXTN (0x02 << BM_COMMAND_STATUS_OFFSET) - */ - -/* Private function prototypes -----------------------------------------------*/ -static uint8_t CCID_CheckCommandParams (uint32_t param_type); - -/* Private functions ---------------------------------------------------------*/ - -/** - * @brief PC_to_RDR_IccPowerOn - * PC_TO_RDR_ICCPOWERON message execution, apply voltage and get ATR - * @param None - * @retval uint8_t status of the command execution - */ -uint8_t PC_to_RDR_IccPowerOn(void) -{ - /* Apply the ICC VCC - Fills the Response buffer with ICC ATR - This Command is returned with RDR_to_PC_DataBlock(); - */ - - uint8_t voltage; - uint8_t sc_voltage = 0; - uint8_t error; - - G_io_ccid.bulk_header.bulkin.dwLength = 0; /* Reset Number of Bytes in abData */ - - error = CCID_CheckCommandParams(CHK_PARAM_SLOT |\ - CHK_PARAM_DWLENGTH | \ - CHK_PARAM_abRFU2 |\ - CHK_PARAM_CARD_PRESENT |\ - CHK_PARAM_ABORT ); - if (error != 0) - { - return error; - } - - /* Voltage that is applied to the ICC - 00h – Automatic Voltage Selection - 01h – 5.0 volts - 02h – 3.0 volts - 03h – 1.8 volts - */ - /* G_io_ccid.bulk_header.bulkout.bSpecific_0 Contains bPowerSelect */ - voltage = G_io_ccid.bulk_header.bulkout.bSpecific_0; - if (voltage >= VOLTAGE_SELECTION_1V8) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - return SLOTERROR_BAD_POWERSELECT; /* The Voltage specified is out of Spec */ - } - - /* Correct Voltage Requested by the Host */ - if ((voltage == VOLTAGE_SELECTION_AUTOMATIC) || - (voltage == VOLTAGE_SELECTION_3V)) - { - /* voltage == 00 Voltage Automatic - voltage == 01 Voltage Automatic = 5.0V - voltage == 02 Voltage Automatic = 3V - voltage == 03 Voltage Automatic = 1.8V - */ - sc_voltage = SC_VOLTAGE_3V; - } - else if (voltage == VOLTAGE_SELECTION_5V) - { - sc_voltage = SC_VOLTAGE_5V; - } - - G_io_ccid.bulk_header.bulkin.dwLength = SC_AnswerToReset(sc_voltage, G_io_ccid_data_buffer); - - /* Check if the Card has come to Active State*/ - error = CCID_CheckCommandParams(CHK_ACTIVE_STATE); - if (error != 0) - { - /* Check if Voltage is not Automatic */ - if (voltage != 0) - { /* If Specific Voltage requested by Host i.e 3V or 5V*/ - return error; - } - else - {/* Automatic Voltage selection requested by Host */ - - if (sc_voltage != SC_VOLTAGE_5V) - { /* If voltage selected was Automatic and 5V is not yet tried */ - sc_voltage = SC_VOLTAGE_5V; - G_io_ccid.bulk_header.bulkin.dwLength = SC_AnswerToReset(sc_voltage, G_io_ccid_data_buffer); - - /* Check again the State */ - error = CCID_CheckCommandParams(CHK_ACTIVE_STATE); - if (error != 0) - return error; - - } - else - { /* Voltage requested from Host was 5V already*/ - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_INACTIVE); - return error; - } - } /* Voltage Selection was automatic */ - } /* If Active State */ - - /* ATR is received, No Error Condition Found */ - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR, BM_ICC_PRESENT_ACTIVE); - - return SLOT_NO_ERROR; -} - -/** - * @brief PC_to_RDR_IccPowerOff - * Icc VCC is switched Off - * @param None - * @retval uint8_t error: status of the command execution - */ -uint8_t PC_to_RDR_IccPowerOff(void) -{ - /* The response to this command message is the RDR_to_PC_SlotStatus - response message. */ - uint8_t error; - - error = CCID_CheckCommandParams(CHK_PARAM_SLOT |\ - CHK_PARAM_abRFU3 |\ - CHK_PARAM_DWLENGTH ); - if (error != 0) - { - return error; - } - - /* Command is ok, Check for Card Presence */ - if (SC_Detect()) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR,BM_ICC_PRESENT_INACTIVE); - } - else - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR,BM_ICC_NO_ICC_PRESENT); - } - - /* Power OFF the card */ - SC_Poweroff(); - - return SLOT_NO_ERROR; -} - -/** - * @brief PC_to_RDR_GetSlotStatus - * Provides the Slot status to the host - * @param None - * @retval uint8_t status of the command execution - */ -uint8_t PC_to_RDR_GetSlotStatus(void) -{ - uint8_t error; - - error = CCID_CheckCommandParams(CHK_PARAM_SLOT |\ - CHK_PARAM_DWLENGTH |\ - CHK_PARAM_CARD_PRESENT |\ - CHK_PARAM_abRFU3 ); - if (error != 0) - { - return error; - } - - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR,BM_ICC_PRESENT_ACTIVE); - return SLOT_NO_ERROR; -} - - -/** - * @brief PC_to_RDR_XfrBlock - * Handles the Block transfer from Host. - * Response to this command message is the RDR_to_PC_DataBlock - * @param None - * @retval uint8_t status of the command execution - */ -uint8_t PC_to_RDR_XfrBlock(void) -{ - uint16_t expectedLength, reqlen; - - uint8_t error; - - error = CCID_CheckCommandParams(CHK_PARAM_SLOT |\ - CHK_PARAM_CARD_PRESENT |\ - CHK_PARAM_abRFU3 |\ - CHK_PARAM_ABORT |\ - CHK_ACTIVE_STATE ); - if (error != 0) - return error; - - if (G_io_ccid.bulk_header.bulkout.dwLength > IO_CCID_DATA_BUFFER_SIZE) - { /* Check amount of Data Sent by Host is > than memory allocated ? */ - - return SLOTERROR_BAD_DWLENGTH; - } - - - /* wLevelParameter = Size of expected data to be returned by the - bulk-IN endpoint */ - expectedLength = (G_io_ccid.bulk_header.bulkout.bSpecific_2 << 8) | - G_io_ccid.bulk_header.bulkout.bSpecific_1; - - reqlen = G_io_ccid.bulk_header.bulkout.dwLength; - - G_io_ccid.bulk_header.bulkin.dwLength = (uint16_t)expectedLength; - - - error = SC_XferBlock(&G_io_ccid_data_buffer[0], - reqlen, - &expectedLength); - - if (error != SLOT_NO_ERROR) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - } - else - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR, BM_ICC_PRESENT_ACTIVE); - error = SLOT_NO_ERROR; - } - - return error; -} - - -/** - * @brief PC_to_RDR_GetParameters - * Provides the ICC parameters to the host - * Response to this command message is the RDR_to_PC_Parameters - * @param None - * @retval uint8_t status of the command execution - */ -uint8_t PC_to_RDR_GetParameters(void) -{ - uint8_t error; - - error = CCID_CheckCommandParams(CHK_PARAM_SLOT |\ - CHK_PARAM_DWLENGTH |\ - CHK_PARAM_CARD_PRESENT |\ - CHK_PARAM_abRFU3 ); - if (error != 0) - return error; - - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR, BM_ICC_PRESENT_ACTIVE); - - return SLOT_NO_ERROR; -} - - -/** - * @brief PC_to_RDR_ResetParameters - * Set the ICC parameters to the default - * Response to this command message is the RDR_to_PC_Parameters - * @param None - * @retval uint8_t status of the command execution - */ -uint8_t PC_to_RDR_ResetParameters(void) -{ - uint8_t error; - - error = CCID_CheckCommandParams(CHK_PARAM_SLOT |\ - CHK_PARAM_DWLENGTH |\ - CHK_PARAM_CARD_PRESENT |\ - CHK_PARAM_abRFU3 |\ - CHK_ACTIVE_STATE); - if (error != 0) - return error; - - /* This command resets the slot parameters to their default values */ - G_io_ccid.Protocol0_DataStructure.bmFindexDindex = DEFAULT_FIDI; - G_io_ccid.Protocol0_DataStructure.bmTCCKST0 = DEFAULT_T01CONVCHECKSUM; - G_io_ccid.Protocol0_DataStructure.bGuardTimeT0 = DEFAULT_EXTRA_GUARDTIME; - G_io_ccid.Protocol0_DataStructure.bWaitingIntegerT0 = DEFAULT_WAITINGINTEGER; - G_io_ccid.Protocol0_DataStructure.bClockStop = DEFAULT_CLOCKSTOP; - - error = SC_SetParams(&G_io_ccid.Protocol0_DataStructure); - - if (error != SLOT_NO_ERROR) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - } - else - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR, BM_ICC_PRESENT_ACTIVE); - error = SLOT_NO_ERROR; - } - - return error; -} - - -/** - * @brief PC_to_RDR_SetParameters - * Set the ICC parameters to the host defined parameters - * Response to this command message is the RDR_to_PC_Parameters - * @param None - * @retval uint8_t status of the command execution - */ -uint8_t PC_to_RDR_SetParameters(void) -{ - uint8_t error; - - error = CCID_CheckCommandParams(CHK_PARAM_SLOT |\ - CHK_PARAM_CARD_PRESENT |\ - CHK_PARAM_abRFU2 |\ - CHK_ACTIVE_STATE); - if (error != 0) - return error; - - error = SLOT_NO_ERROR; - - /* for Protocol T=0 (bProtocolNum=0) (dwLength=00000005h) */ - if ( (G_io_ccid.bulk_header.bulkout.dwLength == 5) && - (G_io_ccid.bulk_header.bulkout.bSpecific_0 != 0)) - error = SLOTERROR_BAD_PROTOCOLNUM; - - /* for Protocol T=1 (bProtocolNum=1) (dwLength=00000007h) */ - if ( (G_io_ccid.bulk_header.bulkout.dwLength == 7) && - (G_io_ccid.bulk_header.bulkout.bSpecific_0 != 1)) - error = SLOTERROR_CMD_NOT_SUPPORTED; - - /* For T0, Waiting Integer 0 supported */ - if (G_io_ccid_data_buffer[3] != 0) - error = SLOTERROR_BAD_WAITINGINTEGER; - - if (G_io_ccid_data_buffer[4] != DEFAULT_CLOCKSTOP) - error = SLOTERROR_BAD_CLOCKSTOP; - - if (error != SLOT_NO_ERROR) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - } - - os_memmove(&G_io_ccid.Protocol0_DataStructure, (Protocol0_DataStructure_t*)(&(G_io_ccid_data_buffer[0])), sizeof(Protocol0_DataStructure_t)); - error = SC_SetParams(&G_io_ccid.Protocol0_DataStructure); - - if (error != SLOT_NO_ERROR) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - } - else - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR, BM_ICC_PRESENT_ACTIVE); - error = SLOT_NO_ERROR; - } - - return error; -} - - -/** - * @brief PC_to_RDR_Escape - * Execute the Escape command. This is user specific Implementation - * Response to this command message is the RDR_to_PC_Escape - * @param None - * @retval uint8_t status of the command execution - */ -uint8_t PC_to_RDR_Escape(void) -{ - uint8_t error; - uint16_t size; - - error = CCID_CheckCommandParams(CHK_PARAM_SLOT |\ - CHK_PARAM_CARD_PRESENT |\ - CHK_PARAM_abRFU3 |\ - CHK_PARAM_ABORT |\ - CHK_ACTIVE_STATE); - - if (error != 0) - return error; - - error = SC_ExecuteEscape(&G_io_ccid_data_buffer[0], - G_io_ccid.bulk_header.bulkout.dwLength, - &G_io_ccid_data_buffer[0], - &size); - - G_io_ccid.bulk_header.bulkin.dwLength = size; - - if (error != SLOT_NO_ERROR) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - } - else - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR, BM_ICC_PRESENT_ACTIVE); - } - - return error; -} - - -/** - * @brief PC_to_RDR_IccClock - * Execute the Clock specific command from host - * Response to this command message is the RDR_to_PC_SlotStatus - * @param None - * @retval uint8_t status of the command execution - */ -uint8_t PC_to_RDR_IccClock(void) -{ - uint8_t error; - - error = CCID_CheckCommandParams(CHK_PARAM_SLOT |\ - CHK_PARAM_CARD_PRESENT |\ - CHK_PARAM_abRFU2 |\ - CHK_PARAM_DWLENGTH|\ - CHK_ACTIVE_STATE); - if (error != 0) - return error; - - /* bClockCommand • 00h restarts Clock - • 01h Stops Clock in the state shown in the bClockStop - field of the PC_to_RDR_SetParameters command - and RDR_to_PC_Parameters message.*/ - if (G_io_ccid.bulk_header.bulkout.bSpecific_0 > 1) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - return SLOTERROR_BAD_CLOCKCOMMAND; - } - - error = SC_SetClock(G_io_ccid.bulk_header.bulkout.bSpecific_0); - - if (error != SLOT_NO_ERROR) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - } - else - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR, BM_ICC_PRESENT_ACTIVE); - } - - return error; -} - - -/** - * @brief PC_to_RDR_Abort - * Execute the Abort command from host, This stops all Bulk transfers - * from host and ICC - * Response to this command message is the RDR_to_PC_SlotStatus - * @param None - * @retval uint8_t status of the command execution - */ -uint8_t PC_to_RDR_Abort(void) -{ - uint8_t error; - - error = CCID_CheckCommandParams(CHK_PARAM_SLOT |\ - CHK_PARAM_abRFU3 |\ - CHK_PARAM_DWLENGTH); - if (error != 0) - return error; - - CCID_CmdAbort (G_io_ccid.bulk_header.bulkout.bSlot, G_io_ccid.bulk_header.bulkout.bSeq); - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR,BM_ICC_PRESENT_ACTIVE); - return SLOT_NO_ERROR; -} - -/** - * @brief CCID_CmdAbort - * Execute the Abort command from Bulk EP or from Control EP, - * This stops all Bulk transfers from host and ICC - * @param uint8_t slot: slot number that host wants to abort - * @param uint8_t seq : Seq number for PC_to_RDR_Abort - * @retval uint8_t status of the command execution - */ -uint8_t CCID_CmdAbort(uint8_t slot, uint8_t seq) -{ - /* This function is called for REQUEST_ABORT & PC_to_RDR_Abort */ - - if (slot >= CCID_NUMBER_OF_SLOTS) - { /* This error condition is possible only from CLASS_REQUEST, otherwise - Slot is already checked in parameters from PC_to_RDR_Abort request */ - /* Slot requested is more than supported by Firmware */ - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED,BM_ICC_NO_ICC_PRESENT); - return SLOTERROR_BAD_SLOT; - } - - if ( G_io_ccid.usb_ccid_param.bAbortRequestFlag == 1) - { /* Abort Command was already received from ClassReq or PC_to_RDR */ - if (( G_io_ccid.usb_ccid_param.bSeq == seq) && (G_io_ccid.usb_ccid_param.bSlot == slot)) - { - /* CLASS Specific request is already Received, Reset the abort flag */ - G_io_ccid.usb_ccid_param.bAbortRequestFlag = 0; - } - } - else - { - /* Abort Command was NOT received from ClassReq or PC_to_RDR, - so save them for next ABORT command to verify */ - G_io_ccid.usb_ccid_param.bAbortRequestFlag = 1; - G_io_ccid.usb_ccid_param.bSeq = seq ; - G_io_ccid.usb_ccid_param.bSlot = slot; - } - - return 0; -} - -/** - * @brief PC_TO_RDR_T0Apdu - * Execute the PC_TO_RDR_T0APDU command from host - * Response to this command message is the RDR_to_PC_SlotStatus - * @param None - * @retval uint8_t status of the command execution - */ -uint8_t PC_TO_RDR_T0Apdu(void) -{ - uint8_t error; - - error = CCID_CheckCommandParams(CHK_PARAM_SLOT |\ - CHK_PARAM_CARD_PRESENT |\ - CHK_PARAM_DWLENGTH | - CHK_PARAM_ABORT ); - if (error != 0) - return error; - - if (G_io_ccid.bulk_header.bulkout.bSpecific_0 > 0x03) - {/* Bit 0 is associated with field bClassGetResponse - Bit 1 is associated with field bClassEnvelope - Other bits are RFU.*/ - - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - return SLOTERROR_BAD_BMCHANGES; - } - - error = SC_T0Apdu(G_io_ccid.bulk_header.bulkout.bSpecific_0, - G_io_ccid.bulk_header.bulkout.bSpecific_1, - G_io_ccid.bulk_header.bulkout.bSpecific_2); - - if (error != SLOT_NO_ERROR) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - } - else - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR, BM_ICC_PRESENT_ACTIVE); - } - - return error; -} - -/** - * @brief PC_TO_RDR_Mechanical - * Execute the PC_TO_RDR_MECHANICAL command from host - * Response to this command message is the RDR_to_PC_SlotStatus - * @param None - * @retval uint8_t status of the command execution - */ -uint8_t PC_TO_RDR_Mechanical(void) -{ - uint8_t error; - - error = CCID_CheckCommandParams(CHK_PARAM_SLOT |\ - CHK_PARAM_CARD_PRESENT |\ - CHK_PARAM_abRFU2 |\ - CHK_PARAM_DWLENGTH - ); - if (error != 0) - return error; - - if (G_io_ccid.bulk_header.bulkout.bSpecific_0 > 0x05) - {/* 01h – Accept Card - 02h – Eject Card - 03h – Capture Card - 04h – Lock Card - 05h – Unlock Card*/ - - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - return SLOTERROR_BAD_BFUNCTION_MECHANICAL; - } - - error = SC_Mechanical(G_io_ccid.bulk_header.bulkout.bSpecific_0); - - if (error != SLOT_NO_ERROR) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - } - else - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR, BM_ICC_PRESENT_ACTIVE); - } - - return error; -} - -/** - * @brief PC_TO_RDR_SetDataRateAndClockFrequency - * Set the required Card Frequency and Data rate from the host. - * Response to this command message is the - * RDR_to_PC_DataRateAndClockFrequency - * @param None - * @retval uint8_t status of the command execution - */ -uint8_t PC_TO_RDR_SetDataRateAndClockFrequency(void) -{ - uint8_t error; - uint32_t clockFrequency; - uint32_t dataRate; - uint32_t temp =0; - - error = CCID_CheckCommandParams(CHK_PARAM_SLOT |\ - CHK_PARAM_CARD_PRESENT |\ - CHK_PARAM_abRFU3); - if (error != 0) - return error; - - if (G_io_ccid.bulk_header.bulkout.dwLength != 0x08) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED,BM_ICC_PRESENT_ACTIVE); - return SLOTERROR_BAD_LENTGH; - } - - /* HERE we avoiding to an unaligned memory access*/ - clockFrequency = U4LE(G_io_ccid_data_buffer, 0); - dataRate = U4LE(G_io_ccid_data_buffer, 4); - - error = SC_SetDataRateAndClockFrequency(clockFrequency, dataRate); - G_io_ccid.bulk_header.bulkin.bError = error; - - if (error != SLOT_NO_ERROR) - { - G_io_ccid.bulk_header.bulkin.dwLength = 0; - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - } - else - { - G_io_ccid.bulk_header.bulkin.dwLength = 8; - - (G_io_ccid_data_buffer[0]) = clockFrequency & 0x000000FF ; - (G_io_ccid_data_buffer[1]) = (clockFrequency & 0x0000FF00) >> 8; - (G_io_ccid_data_buffer[2]) = (clockFrequency & 0x00FF0000) >> 16; - (G_io_ccid_data_buffer[3]) = (clockFrequency & 0xFF000000) >> 24; - (G_io_ccid_data_buffer[4]) = dataRate & 0x000000FF ; - (G_io_ccid_data_buffer[5]) = (dataRate & 0x0000FF00) >> 8; - (G_io_ccid_data_buffer[6]) = (dataRate & 0x00FF0000) >> 16; - (G_io_ccid_data_buffer[7]) = (dataRate & 0xFF000000) >> 24; - - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR, BM_ICC_PRESENT_ACTIVE); - } - - return error; -} - -/** - * @brief PC_TO_RDR_Secure - * Execute the Secure Command from the host. - * Response to this command message is the RDR_to_PC_DataBlock - * @param None - * @retval uint8_t status of the command execution - */ -uint8_t PC_TO_RDR_Secure(void) -{ - uint8_t error; - uint8_t bBWI; - uint16_t wLevelParameter; - uint32_t responseLen; - - - error = CCID_CheckCommandParams(CHK_PARAM_SLOT |\ - CHK_PARAM_CARD_PRESENT |\ - CHK_PARAM_ABORT ); - - if (error != 0) { - G_io_ccid.bulk_header.bulkin.dwLength = 0; - return error; - } - - bBWI = G_io_ccid.bulk_header.bulkout.bSpecific_0; - wLevelParameter = (G_io_ccid.bulk_header.bulkout.bSpecific_1 + ((uint16_t)G_io_ccid.bulk_header.bulkout.bSpecific_2<<8)); - - if ((EXCHANGE_LEVEL_FEATURE == TPDU_EXCHANGE) || - (EXCHANGE_LEVEL_FEATURE == SHORT_APDU_EXCHANGE)) - { - /* TPDU level & short APDU level, wLevelParameter is RFU, = 0000h */ - if (wLevelParameter != 0 ) - { - G_io_ccid.bulk_header.bulkin.dwLength = 0; - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - error = SLOTERROR_BAD_LEVELPARAMETER; - return error; - } - } - - error = SC_Secure(G_io_ccid.bulk_header.bulkout.dwLength - CCID_HEADER_SIZE, bBWI, wLevelParameter, - &G_io_ccid_data_buffer[0], &responseLen); - - G_io_ccid.bulk_header.bulkin.dwLength = responseLen; - - if (error != SLOT_NO_ERROR) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED, BM_ICC_PRESENT_ACTIVE); - } - else - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_NO_ERROR, BM_ICC_PRESENT_ACTIVE); - } - - return error; -} - -/******************************************************************************/ -/* BULK IN ROUTINES */ -/******************************************************************************/ - -/** - * @brief RDR_to_PC_DataBlock - * Provide the data block response to the host - * Response for PC_to_RDR_IccPowerOn, PC_to_RDR_XfrBlock - * @param uint8_t errorCode: code to be returned to the host - * @retval None - */ -void RDR_to_PC_DataBlock(uint8_t errorCode) -{ - G_io_ccid.bulk_header.bulkin.bMessageType = RDR_TO_PC_DATABLOCK; - G_io_ccid.bulk_header.bulkin.bError = errorCode; - G_io_ccid.bulk_header.bulkin.bSpecific=0; /* bChainParameter */ - - /* void the Length Specified in Command */ - if(errorCode != SLOT_NO_ERROR) - { - G_io_ccid.bulk_header.bulkin.dwLength = 0; - } - - Transfer_Data_Request(); - -} - - -/** - * @brief RDR_to_PC_SlotStatus - * Provide the Slot status response to the host - * Response for PC_to_RDR_IccPowerOff - * PC_to_RDR_GetSlotStatus - * PC_to_RDR_IccClock - * PC_to_RDR_T0APDU - * PC_to_RDR_Mechanical - * Also the device sends this response message when it has completed - * aborting a slot after receiving both the Class Specific ABORT request - * and PC_to_RDR_Abort command message. - * @param uint8_t errorCode: code to be returned to the host - * @retval None - */ -void RDR_to_PC_SlotStatus(uint8_t errorCode) -{ - - G_io_ccid.bulk_header.bulkin.bMessageType = RDR_TO_PC_SLOTSTATUS; - G_io_ccid.bulk_header.bulkin.dwLength =0; - G_io_ccid.bulk_header.bulkin.bError = errorCode; - G_io_ccid.bulk_header.bulkin.bSpecific=0; /* bClockStatus = 00h Clock running - 01h Clock stopped in state L - 02h Clock stopped in state H - 03h Clock stopped in an unknown state - All other values are RFU. */ - - Transfer_Data_Request(); - -} - -/** - * @brief RDR_to_PC_Parameters - * Provide the data block response to the host - * Response for PC_to_RDR_GetParameters, PC_to_RDR_ResetParameters - * PC_to_RDR_SetParameters - * @param uint8_t errorCode: code to be returned to the host - * @retval None - */ -void RDR_to_PC_Parameters(uint8_t errorCode) -{ - - G_io_ccid.bulk_header.bulkin.bMessageType = RDR_TO_PC_PARAMETERS; - G_io_ccid.bulk_header.bulkin.bError = errorCode; - - if(errorCode == SLOT_NO_ERROR) - { - G_io_ccid.bulk_header.bulkin.dwLength = LEN_PROTOCOL_STRUCT_T0; - } - else - { - G_io_ccid.bulk_header.bulkin.dwLength = 0; - } - - os_memmove(G_io_ccid_data_buffer, &G_io_ccid.Protocol0_DataStructure, sizeof(G_io_ccid.Protocol0_DataStructure)); - - /* bProtocolNum */ - G_io_ccid.bulk_header.bulkin.bSpecific = BPROTOCOL_NUM_T0; - - Transfer_Data_Request(); -} - -/** - * @brief RDR_to_PC_Escape - * Provide the Escaped data block response to the host - * Response for PC_to_RDR_Escape - * @param uint8_t errorCode: code to be returned to the host - * @retval None - */ -void RDR_to_PC_Escape(uint8_t errorCode) -{ - G_io_ccid.bulk_header.bulkin.bMessageType = RDR_TO_PC_ESCAPE; - - G_io_ccid.bulk_header.bulkin.bSpecific=0; /* Reserved for Future Use */ - G_io_ccid.bulk_header.bulkin.bError = errorCode; - - /* void the Length Specified in Command */ - if(errorCode != SLOT_NO_ERROR) - { - G_io_ccid.bulk_header.bulkin.dwLength = 0; - } - - Transfer_Data_Request(); -} - - - -/** - * @brief RDR_to_PC_DataRateAndClockFrequency - * Provide the Clock and Data Rate information to host - * Response for PC_TO_RDR_SetDataRateAndClockFrequency - * @param uint8_t errorCode: code to be returned to the host - * @retval None - */ -void RDR_to_PC_DataRateAndClockFrequency(uint8_t errorCode) -{ - /* - uint16_t length = CCID_RESPONSE_HEADER_SIZE; - */ - - G_io_ccid.bulk_header.bulkin.bMessageType = RDR_TO_PC_DATARATEANDCLOCKFREQUENCY; - G_io_ccid.bulk_header.bulkin.bError = errorCode; - G_io_ccid.bulk_header.bulkin.bSpecific=0; /* Reserved for Future Use */ - - /* void the Length Specified in Command */ - if(errorCode != SLOT_NO_ERROR) - { - G_io_ccid.bulk_header.bulkin.dwLength = 0; - } - - Transfer_Data_Request(); -} - -#ifdef HAVE_CCID_INTERRUPT -/** - * @brief RDR_to_PC_NotifySlotChange - * Interrupt message to be sent to the host, Checks the card presence - * status and update the buffer accordingly - * @param None - * @retval None - */ -void RDR_to_PC_NotifySlotChange(void) -{ - G_io_ccid.UsbIntMessageBuffer[OFFSET_INT_BMESSAGETYPE] = RDR_TO_PC_NOTIFYSLOTCHANGE; - - if (SC_Detect() ) - { - /* - SLOT_ICC_PRESENT 0x01 : LSb : (0b = no ICC present, 1b = ICC present) - SLOT_ICC_CHANGE 0x02 : MSb : (0b = no change, 1b = change). - */ - G_io_ccid.UsbIntMessageBuffer[OFFSET_INT_BMSLOTICCSTATE] = SLOT_ICC_PRESENT | - SLOT_ICC_CHANGE; - } - else - { - G_io_ccid.UsbIntMessageBuffer[OFFSET_INT_BMSLOTICCSTATE] = SLOT_ICC_CHANGE; - - /* Power OFF the card */ - SC_Poweroff(); - } -} -#endif // HAVE_CCID_INTERRUPT - - -/** - * @brief CCID_UpdSlotStatus - * Updates the variable for the slot status - * @param uint8_t slotStatus : slot status from the calling function - * @retval None - */ -void CCID_UpdSlotStatus (uint8_t slotStatus) -{ - G_io_ccid.Ccid_SlotStatus.SlotStatus = slotStatus; -} - -/** - * @brief CCID_UpdSlotChange - * Updates the variable for the slot change status - * @param uint8_t changeStatus : slot change status from the calling function - * @retval None - */ -void CCID_UpdSlotChange (uint8_t changeStatus) -{ - G_io_ccid.Ccid_SlotStatus.SlotStatusChange = changeStatus; -} - -/** - * @brief CCID_IsSlotStatusChange - * Provides the value of the variable for the slot change status - * @param None - * @retval uint8_t slot change status - */ -uint8_t CCID_IsSlotStatusChange (void) -{ - return G_io_ccid.Ccid_SlotStatus.SlotStatusChange; -} - -/** - * @brief CCID_CheckCommandParams - * Checks the specific parameters requested by the function and update - * status accordingly. This function is called from all - * PC_to_RDR functions - * @param uint32_t param_type : Parameter enum to be checked by calling function - * @retval uint8_t status - */ -static uint8_t CCID_CheckCommandParams (uint32_t param_type) -{ - uint32_t parameter; - - G_io_ccid.bulk_header.bulkin.bStatus = BM_ICC_PRESENT_ACTIVE | BM_COMMAND_STATUS_NO_ERROR ; - - parameter = (uint32_t)param_type; - - if (parameter & CHK_PARAM_SLOT) - { - /* - The slot number (bSlot) identifies which ICC slot is being addressed - by the message, if the CCID supports multiple slots. - The slot number is zero-relative, and is in the range of zero to FFh. - */ - - /* SLOT Number is 0 onwards, so always < CCID_NUMBER_OF_SLOTs */ - /* Error Condition !!! */ - if (G_io_ccid.bulk_header.bulkout.bSlot >= CCID_NUMBER_OF_SLOTS) - { /* Slot requested is more than supported by Firmware */ - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED,BM_ICC_NO_ICC_PRESENT); - return SLOTERROR_BAD_SLOT; - } - } - - if (parameter & CHK_PARAM_CARD_PRESENT) - { - /* Commands Parameters ok, Check the Card Status */ - if (SC_Detect() == 0) - { /* Card is Not detected */ - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED,BM_ICC_NO_ICC_PRESENT); - return SLOTERROR_ICC_MUTE; - } - } - - /* Check that DwLength is 0 */ - if (parameter & CHK_PARAM_DWLENGTH) - { - if (G_io_ccid.bulk_header.bulkout.dwLength != 0) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED,BM_ICC_PRESENT_ACTIVE); - return SLOTERROR_BAD_LENTGH; - } - } - - /* abRFU 2 : Reserved for Future Use*/ - if (parameter & CHK_PARAM_abRFU2) - { - - if ((G_io_ccid.bulk_header.bulkout.bSpecific_1 != 0) || - (G_io_ccid.bulk_header.bulkout.bSpecific_2 != 0)) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED,BM_ICC_PRESENT_ACTIVE); - return SLOTERROR_BAD_ABRFU_2B; /* bSpecific_1 */ - } - } - - if (parameter & CHK_PARAM_abRFU3) - { - /* abRFU 3 : Reserved for Future Use*/ - if ((G_io_ccid.bulk_header.bulkout.bSpecific_0 != 0) || - (G_io_ccid.bulk_header.bulkout.bSpecific_1 != 0) || - (G_io_ccid.bulk_header.bulkout.bSpecific_2 != 0)) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED,BM_ICC_PRESENT_ACTIVE); - return SLOTERROR_BAD_ABRFU_3B; - } - } - - - if (parameter & CHK_PARAM_ABORT) - { - if( G_io_ccid.usb_ccid_param.bAbortRequestFlag ) - { - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED,BM_ICC_PRESENT_INACTIVE); - return SLOTERROR_CMD_ABORTED; - } - } - - if (parameter & CHK_ACTIVE_STATE) - { - /* Commands Parameters ok, Check the Card Status */ - /* Card is detected */ - if (! SC_Detect()) - { - /* Check that from Lower Layers, the SmartCard come to known state */ - CCID_UpdateCommandStatus(BM_COMMAND_STATUS_FAILED,BM_ICC_PRESENT_INACTIVE); - return SLOTERROR_HW_ERROR; - } - } - - return 0; -} - -#endif // HAVE_USB_CLASS_CCID - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/src/sdk/usbd_ccid_impl.h b/src/sdk/usbd_ccid_impl.h deleted file mode 100644 index eb8dfe0..0000000 --- a/src/sdk/usbd_ccid_impl.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef USBD_CCID_IMPL_H -#define USBD_CCID_IMPL_H - -#ifdef HAVE_USB_CLASS_CCID - -// ================================================ -// CCID - -#define TPDU_EXCHANGE 0x01 -#define SHORT_APDU_EXCHANGE 0x02 -#define EXTENDED_APDU_EXCHANGE 0x04 -#define CHARACTER_EXCHANGE 0x00 - -#define EXCHANGE_LEVEL_FEATURE SHORT_APDU_EXCHANGE - -#define CCID_INTF 2 -#define CCID_BULK_IN_EP 0x83 -#define CCID_BULK_EPIN_SIZE 64 -#define CCID_BULK_OUT_EP 0x03 -#define CCID_BULK_EPOUT_SIZE 64 - -#ifdef HAVE_CCID_INTERRUPT -#define CCID_INTR_IN_EP 0x84 -#define CCID_INTR_EPIN_SIZE 16 -#endif // HAVE_CCID_INTERRUPT - -#define IO_CCID_DATA_BUFFER_SIZE IO_APDU_BUFFER_SIZE -#define G_io_ccid_data_buffer G_io_apdu_buffer - -#endif // HAVE_USB_CLASS_CCID - -#endif // USBD_CCID_IMPL_H diff --git a/src/sdk/usbd_hid_impl.h b/src/sdk/usbd_hid_impl.h deleted file mode 100644 index 8d69655..0000000 --- a/src/sdk/usbd_hid_impl.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef USBD_HID_IMPL_H -#define USBD_HID_IMPL_H - -// ================================================ -// HIDGEN - -#define HID_INTF 0 - -#define HID_EPIN_ADDR 0x82 -#define HID_EPIN_SIZE 0x40 - -#define HID_EPOUT_ADDR 0x02 -#define HID_EPOUT_SIZE 0x40 - -#ifdef HAVE_IO_U2F -// ================================================ -// HID U2F - -#define U2F_INTF 1 - -#define U2F_EPIN_ADDR 0x81 -#define U2F_EPIN_SIZE 0x40 - -#define U2F_EPOUT_ADDR 0x01 -#define U2F_EPOUT_SIZE 0x40 -#endif // HAVE_IO_U2F - -#endif // USBD_HID_IMPL_H - diff --git a/src/sdk/usbd_impl.c b/src/sdk/usbd_impl.c deleted file mode 100644 index 9c82900..0000000 --- a/src/sdk/usbd_impl.c +++ /dev/null @@ -1,916 +0,0 @@ -/** - ****************************************************************************** - * @file usbd_hid.c - * @author MCD Application Team - * @version V2.2.0 - * @date 13-June-2014 - * @brief This file provides the HID core functions. - * - * @verbatim - * - * =================================================================== - * HID Class Description - * =================================================================== - * This module manages the HID class V1.11 following the "Device Class Definition - * for Human Interface Devices (HID) Version 1.11 Jun 27, 2001". - * This driver implements the following aspects of the specification: - * - The Boot Interface Subclass - * - Usage Page : Generic Desktop - * - Usage : Vendor - * - Collection : Application - * - * @note In HS mode and when the DMA is used, all variables and data structures - * dealing with the DMA during the transaction process should be 32-bit aligned. - * - * - * @endverbatim - * - ****************************************************************************** - * @attention - * - *

© COPYRIGHT 2014 STMicroelectronics

- * - * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); - * You may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.st.com/software_license_agreement_liberty_v2 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ****************************************************************************** - */ -#pragma message "Override SDK source file :" __FILE__ - -#include "os.h" - - -/* Includes ------------------------------------------------------------------*/ - -#include "usbd_hid.h" -#include "usbd_hid_impl.h" - -#include "usbd_ctlreq.h" - -#include "usbd_core.h" -#include "usbd_conf.h" - -#include "usbd_def.h" -#include "os_io_seproxyhal.h" - -#ifdef HAVE_IO_U2F -#include "u2f_transport.h" -#include "u2f_impl.h" -#endif // HAVE_IO_U2F - -#ifdef HAVE_USB_CLASS_CCID -#include "usbd_ccid_core.h" -#endif // HAVE_USB_CLASS_CCID - - -/** @addtogroup STM32_USB_DEVICE_LIBRARY - * @{ - */ - - -/** @defgroup USBD_HID - * @brief usbd core module - * @{ - */ - -/** @defgroup USBD_HID_Private_TypesDefinitions - * @{ - */ -/** - * @} - */ - - -/** @defgroup USBD_HID_Private_Defines - * @{ - */ - -/** - * @} - */ - - -/** @defgroup USBD_HID_Private_Macros - * @{ - */ -/** - * @} - */ -/** @defgroup USBD_HID_Private_FunctionPrototypes - * @{ - */ - - -/** - * @} - */ - -/** @defgroup USBD_HID_Private_Variables - * @{ - */ - -#define HID_EPIN_ADDR 0x82 -#define HID_EPIN_SIZE 0x40 - -#define HID_EPOUT_ADDR 0x02 -#define HID_EPOUT_SIZE 0x40 - -#define USBD_LANGID_STRING 0x409 - -#ifdef HAVE_VID_PID_PROBER -#define USBD_VID 0x2581 -#define USBD_PID 0xf1d1 -#else -#define USBD_VID 0x2C97 -#if defined(TARGET_BLUE) // blue -#define USBD_PID 0x0000 -static const uint8_t const USBD_PRODUCT_FS_STRING[] = { - 4*2+2, - USB_DESC_TYPE_STRING, - 'B', 0, - 'l', 0, - 'u', 0, - 'e', 0, -}; - -#elif defined(TARGET_NANOS) // nano s -#define USBD_PID 0x0001 -static const uint8_t const USBD_PRODUCT_FS_STRING[] = { - 6*2+2, - USB_DESC_TYPE_STRING, - 'N', 0, - 'a', 0, - 'n', 0, - 'o', 0, - ' ', 0, - 'S', 0, -}; -#elif defined(TARGET_ARAMIS) // aramis -#define USBD_PID 0x0002 -static const uint8_t const USBD_PRODUCT_FS_STRING[] = { - 6*2+2, - USB_DESC_TYPE_STRING, - 'A', 0, - 'r', 0, - 'a', 0, - 'm', 0, - 'i', 0, - 's', 0, -}; -#else -#error unknown TARGET_ID -#endif -#endif - -/* USB Standard Device Descriptor */ -static const uint8_t const USBD_LangIDDesc[]= -{ - USB_LEN_LANGID_STR_DESC, - USB_DESC_TYPE_STRING, - LOBYTE(USBD_LANGID_STRING), - HIBYTE(USBD_LANGID_STRING), -}; - -static const uint8_t const USB_SERIAL_STRING[] = -{ - 4*2+2, - USB_DESC_TYPE_STRING, - '0', 0, - '0', 0, - '0', 0, - '1', 0, -}; - -static const uint8_t const USBD_MANUFACTURER_STRING[] = { - 6*2+2, - USB_DESC_TYPE_STRING, - 'L', 0, - 'e', 0, - 'd', 0, - 'g', 0, - 'e', 0, - 'r', 0, -}; - -#define USBD_INTERFACE_FS_STRING USBD_PRODUCT_FS_STRING -#define USBD_CONFIGURATION_FS_STRING USBD_PRODUCT_FS_STRING - -static const uint8_t const HID_ReportDesc[] = { - 0x06, 0xA0, 0xFF, // Usage page (vendor defined) - 0x09, 0x01, // Usage ID (vendor defined) - 0xA1, 0x01, // Collection (application) - - // The Input report - 0x09, 0x03, // Usage ID - vendor defined - 0x15, 0x00, // Logical Minimum (0) - 0x26, 0xFF, 0x00, // Logical Maximum (255) - 0x75, 0x08, // Report Size (8 bits) - 0x95, HID_EPIN_SIZE, // Report Count (64 fields) - 0x81, 0x08, // Input (Data, Variable, Absolute) - - // The Output report - 0x09, 0x04, // Usage ID - vendor defined - 0x15, 0x00, // Logical Minimum (0) - 0x26, 0xFF, 0x00, // Logical Maximum (255) - 0x75, 0x08, // Report Size (8 bits) - 0x95, HID_EPOUT_SIZE, // Report Count (64 fields) - 0x91, 0x08, // Output (Data, Variable, Absolute) - 0xC0 -}; - -#ifdef HAVE_IO_U2F -static const uint8_t const HID_ReportDesc_fido[] = { - 0x06, 0xD0, 0xF1, // Usage page (vendor defined) - 0x09, 0x01, // Usage ID (vendor defined) - 0xA1, 0x01, // Collection (application) - - // The Input report - 0x09, 0x03, // Usage ID - vendor defined - 0x15, 0x00, // Logical Minimum (0) - 0x26, 0xFF, 0x00, // Logical Maximum (255) - 0x75, 0x08, // Report Size (8 bits) - 0x95, U2F_EPIN_SIZE, // Report Count (64 fields) - 0x81, 0x08, // Input (Data, Variable, Absolute) - - // The Output report - 0x09, 0x04, // Usage ID - vendor defined - 0x15, 0x00, // Logical Minimum (0) - 0x26, 0xFF, 0x00, // Logical Maximum (255) - 0x75, 0x08, // Report Size (8 bits) - 0x95, U2F_EPOUT_SIZE, // Report Count (64 fields) - 0x91, 0x08, // Output (Data, Variable, Absolute) - 0xC0 -}; -#endif // HAVE_IO_U2F - -#define ARRAY_U2LE(l) (l)&0xFF, (l)>>8 - -/* USB HID device Configuration Descriptor */ -static __ALIGN_BEGIN const uint8_t const N_USBD_CfgDesc[] __ALIGN_END = -{ - 0x09, /* bLength: Configuration Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - ARRAY_U2LE(0x9 /* wTotalLength: Bytes returned */ - +0x9+0x9+0x7+0x7 -#ifdef HAVE_IO_U2F - +0x9+0x9+0x7+0x7 -#endif // HAVE_IO_U2F -#ifdef HAVE_USB_CLASS_CCID - +0x9+0x36+0x7+0x7 -#endif // HAVE_USB_CLASS_CCID - ), - 1 -#ifdef HAVE_IO_U2F - +1 -#endif // HAVE_IO_U2F -#ifdef HAVE_USB_CLASS_CCID - +1 -#endif // HAVE_USB_CLASS_CCID - , /*bNumInterfaces */ - 0x01, /*bConfigurationValue: Configuration value*/ - USBD_IDX_PRODUCT_STR, /*iConfiguration: Index of string descriptor describing the configuration*/ - 0xC0, /*bmAttributes: bus powered */ - 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ - - /* HIDGEN ################################################################################################ */ - - /************** Descriptor of KBD HID interface ****************/ - 0x09, /*bLength: Interface Descriptor size*/ - USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/ - HID_INTF, /*bInterfaceNumber: Number of Interface*/ - 0x00, /*bAlternateSetting: Alternate setting*/ - 0x02, /*bNumEndpoints*/ - 0x03, /*bInterfaceClass: HID*/ - 0x00, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/ - 0x00, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/ - USBD_IDX_PRODUCT_STR, /*iInterface: Index of string descriptor*/ - - /******************** Descriptor of HID *************************/ - 0x09, /*bLength: HID Descriptor size*/ - HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/ - 0x11, /*bHIDUSTOM_HID: HID Class Spec release number*/ - 0x01, - 0x00, /*bCountryCode: Hardware target country*/ - 0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/ - 0x22, /*bDescriptorType*/ - sizeof(HID_ReportDesc),/*wItemLength: Total length of Report descriptor*/ - 0x00, - - /******************** Descriptor of Custom HID endpoints ********************/ - 0x07, /*bLength: Endpoint Descriptor size*/ - USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/ - HID_EPIN_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/ - 0x03, /*bmAttributes: Interrupt endpoint*/ - HID_EPIN_SIZE, /*wMaxPacketSize: 2 Byte max */ - 0x00, - 0x01, /*bInterval: Polling Interval (20 ms)*/ - - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ - HID_EPOUT_ADDR, /*bEndpointAddress: Endpoint Address (OUT)*/ - 0x03, /* bmAttributes: Interrupt endpoint */ - HID_EPOUT_SIZE, /* wMaxPacketSize: 2 Bytes max */ - 0x00, - 0x01, /* bInterval: Polling Interval (20 ms) */ - -#ifdef HAVE_IO_U2F - /* HID FIDO ################################################################################################ */ - - /************** Descriptor of HID FIDO interface ****************/ - 0x09, /*bLength: Interface Descriptor size*/ - USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/ - U2F_INTF, /*bInterfaceNumber: Number of Interface*/ - 0x00, /*bAlternateSetting: Alternate setting*/ - 0x02, /*bNumEndpoints*/ - 0x03, /*bInterfaceClass: HID*/ - 0x01, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/ - 0x01, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/ - USBD_IDX_PRODUCT_STR, /*iInterface: Index of string descriptor*/ - - /******************** Descriptor of HID *************************/ - 0x09, /*bLength: HID Descriptor size*/ - HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/ - 0x11, /*bHIDUSTOM_HID: HID Class Spec release number*/ - 0x01, - 0x21, /*bCountryCode: Hardware target country*/ // 0x21: US, 0x08: FR, 0x0D: ISO Intl - 0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/ - 0x22, /*bDescriptorType*/ - sizeof(HID_ReportDesc_fido),/*wItemLength: Total length of Report descriptor*/ - 0x00, - /******************** Descriptor of Custom HID endpoints ********************/ - 0x07, /*bLength: Endpoint Descriptor size*/ - USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/ - U2F_EPIN_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/ - 0x03, /*bmAttributes: Interrupt endpoint*/ - U2F_EPIN_SIZE, /*wMaxPacketSize: */ - 0x00, - 0x01, /*bInterval: Polling Interval */ - - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ - U2F_EPOUT_ADDR, /*bEndpointAddress: Endpoint Address (OUT)*/ - 0x03, /* bmAttributes: Interrupt endpoint */ - U2F_EPOUT_SIZE, /* wMaxPacketSize: */ - 0x00, - 0x01,/* bInterval: Polling Interval */ -#endif // HAVE_IO_U2F - -#ifdef HAVE_USB_CLASS_CCID - /* CCID ################################################################################################ */ - - /******************** CCID **** interface ********************/ - 0x09, /* bLength: Interface Descriptor size */ - 0x04, /* bDescriptorType: */ - CCID_INTF, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints: endpoints used */ - 0x0B, /* bInterfaceClass: user's interface for CCID */ - 0x00, /* bInterfaceSubClass : */ - 0x00, /* nInterfaceProtocol : None */ - 0x05, /* iInterface: */ - - /******************* CCID class descriptor ********************/ - 0x36, /* bLength: CCID Descriptor size */ - 0x21, /* bDescriptorType: Functional Descriptor type. */ - 0x10, /* bcdCCID(LSB): CCID Class Spec release number (1.00) */ - 0x01, /* bcdCCID(MSB) */ - - 0x00, /* bMaxSlotIndex :highest available slot on this device */ - 0x03, /* bVoltageSupport: bit Wise OR for 01h-5.0V 02h-3.0V - 04h 1.8V*/ - - 0x01,0x00,0x00,0x00, /* dwProtocols: 0001h = Protocol T=0 */ - 0x10,0x0E,0x00,0x00, /* dwDefaultClock: 3.6Mhz = 3600kHz = 0x0E10, - for 4 Mhz the value is (0x00000FA0) : - This is used in ETU and waiting time calculations*/ - 0x10,0x0E,0x00,0x00, /* dwMaximumClock: Maximum supported ICC clock frequency - in KHz. So, 3.6Mhz = 3600kHz = 0x0E10, - 4 Mhz (0x00000FA0) : */ - 0x00, /* bNumClockSupported : no setting from PC - If the value is 00h, the - supported clock frequencies are assumed to be the - default clock frequency defined by dwDefaultClock - and the maximum clock frequency defined by - dwMaximumClock */ - - 0xCD,0x25,0x00,0x00, /* dwDataRate: Default ICC I/O data rate in bps - 9677 bps = 0x25CD - for example 10752 bps (0x00002A00) */ - - 0xCD,0x25,0x00,0x00, /* dwMaxDataRate: Maximum supported ICC I/O data - rate in bps */ - 0x00, /* bNumDataRatesSupported : - The number of data rates that are supported by the CCID - If the value is 00h, all data rates between the default - data rate dwDataRate and the maximum data rate - dwMaxDataRate are supported. - Dont support GET_CLOCK_FREQUENCIES - */ - //46 - 0x00,0x00,0x00,0x00, /* dwMaxIFSD: 0 (T=0 only) */ - 0x00,0x00,0x00,0x00, /* dwSynchProtocols */ - 0x00,0x00,0x00,0x00, /* dwMechanical: no special characteristics */ - - 0xBA, 0x06, 0x02, 0x00, - //0x38,0x00,EXCHANGE_LEVEL_FEATURE,0x00, - /* dwFeatures: clk, baud rate, voltage : automatic */ - /* 00000008h Automatic ICC voltage selection - 00000010h Automatic ICC clock frequency change - 00000020h Automatic baud rate change according to - active parameters provided by the Host or self - determined 00000100h CCID can set - ICC in clock stop mode - - Only one of the following values may be present to - select a level of exchange: - 00010000h TPDU level exchanges with CCID - 00020000h Short APDU level exchange with CCID - 00040000h Short and Extended APDU level exchange - If none of those values : character level of exchange*/ - 0x0F,0x01,0x00,0x00, /* dwMaxCCIDMessageLength: Maximum block size + header*/ - /* 261 + 10 */ - - 0x00, /* bClassGetResponse*/ - 0x00, /* bClassEnvelope */ - 0x00,0x00, /* wLcdLayout : 0000h no LCD. */ - 0x00, /* bPINSupport : no PIN verif and modif */ - 0x01, /* bMaxCCIDBusySlots */ - - /******************** CCID Endpoints ********************/ - 0x07, /*Endpoint descriptor length = 7*/ - 0x05, /*Endpoint descriptor type */ - CCID_BULK_IN_EP, /*Endpoint address (IN, address 1) */ - 0x02, /*Bulk endpoint type */ - LOBYTE(CCID_BULK_EPIN_SIZE), - HIBYTE(CCID_BULK_EPIN_SIZE), - 0x00, /*Polling interval in milliseconds */ - - 0x07, /*Endpoint descriptor length = 7 */ - 0x05, /*Endpoint descriptor type */ - CCID_BULK_OUT_EP, /*Endpoint address (OUT, address 1) */ - 0x02, /*Bulk endpoint type */ - LOBYTE(CCID_BULK_EPOUT_SIZE), - HIBYTE(CCID_BULK_EPOUT_SIZE), - 0x00, /*Polling interval in milliseconds*/ -#endif // HAVE_USB_CLASS_CCID -} ; - -#ifdef HAVE_IO_U2F -/* USB HID device Configuration Descriptor */ -__ALIGN_BEGIN const uint8_t const USBD_HID_Desc_fido[] __ALIGN_END = -{ - /******************** Descriptor of HID *************************/ - 0x09, /*bLength: HID Descriptor size*/ - HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/ - 0x11, /*bHIDUSTOM_HID: HID Class Spec release number*/ - 0x01, - 0x21, /*bCountryCode: Hardware target country*/ // 0x21: US, 0x08: FR, 0x0D: ISO Intl - 0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/ - 0x22, /*bDescriptorType*/ - sizeof(HID_ReportDesc_fido),/*wItemLength: Total length of Report descriptor*/ - 0x00, -}; -#endif // HAVE_IO_U2F - -/* USB HID device Configuration Descriptor */ -__ALIGN_BEGIN const uint8_t const USBD_HID_Desc[] __ALIGN_END = -{ - /* 18 */ - 0x09, /*bLength: HID Descriptor size*/ - HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/ - 0x11, /*bHIDUSTOM_HID: HID Class Spec release number*/ - 0x01, - 0x00, /*bCountryCode: Hardware target country*/ - 0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/ - 0x22, /*bDescriptorType*/ - sizeof(HID_ReportDesc),/*wItemLength: Total length of Report descriptor*/ - 0x00, -}; - -/* USB Standard Device Descriptor */ -static __ALIGN_BEGIN const uint8_t const USBD_DeviceQualifierDesc[] __ALIGN_END = -{ - USB_LEN_DEV_QUALIFIER_DESC, - USB_DESC_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x01, - 0x00, -}; - -/* USB Standard Device Descriptor */ -static const uint8_t const USBD_DeviceDesc[]= { - 0x12, /* bLength */ - USB_DESC_TYPE_DEVICE, /* bDescriptorType */ - 0x00, /* bcdUSB */ - 0x02, - 0x00, /* bDeviceClass */ - 0x00, /* bDeviceSubClass */ - 0x00, /* bDeviceProtocol */ - USB_MAX_EP0_SIZE, /* bMaxPacketSize */ - LOBYTE(USBD_VID), /* idVendor */ - HIBYTE(USBD_VID), /* idVendor */ - LOBYTE(USBD_PID), /* idVendor */ - HIBYTE(USBD_PID), /* idVendor */ - 0x00, /* bcdDevice rel. 2.00 */ - 0x02, - USBD_IDX_MFC_STR, /* Index of manufacturer string */ - USBD_IDX_PRODUCT_STR, /* Index of product string */ - USBD_IDX_SERIAL_STR, /* Index of serial number string */ - 1 /* bNumConfigurations */ -}; /* USB_DeviceDescriptor */ - - -/** - * @brief Returns the device descriptor. - * @param speed: Current device speed - * @param length: Pointer to data length variable - * @retval Pointer to descriptor buffer - */ -uint8_t *USBD_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) -{ - UNUSED(speed); - *length = sizeof(USBD_DeviceDesc); - return (uint8_t*)USBD_DeviceDesc; -} - -/** - * @brief Returns the LangID string descriptor. - * @param speed: Current device speed - * @param length: Pointer to data length variable - * @retval Pointer to descriptor buffer - */ -uint8_t *USBD_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) -{ - UNUSED(speed); - *length = sizeof(USBD_LangIDDesc); - return (uint8_t*)USBD_LangIDDesc; -} - -/** - * @brief Returns the product string descriptor. - * @param speed: Current device speed - * @param length: Pointer to data length variable - * @retval Pointer to descriptor buffer - */ -uint8_t *USBD_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) -{ - UNUSED(speed); - *length = sizeof(USBD_PRODUCT_FS_STRING); - return (uint8_t*)USBD_PRODUCT_FS_STRING; -} - -/** - * @brief Returns the manufacturer string descriptor. - * @param speed: Current device speed - * @param length: Pointer to data length variable - * @retval Pointer to descriptor buffer - */ -uint8_t *USBD_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) -{ - UNUSED(speed); - *length = sizeof(USBD_MANUFACTURER_STRING); - return (uint8_t*)USBD_MANUFACTURER_STRING; -} - -/** - * @brief Returns the serial number string descriptor. - * @param speed: Current device speed - * @param length: Pointer to data length variable - * @retval Pointer to descriptor buffer - */ -uint8_t *USBD_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) -{ - UNUSED(speed); - *length = sizeof(USB_SERIAL_STRING); - return (uint8_t*)USB_SERIAL_STRING; -} - -/** - * @brief Returns the configuration string descriptor. - * @param speed: Current device speed - * @param length: Pointer to data length variable - * @retval Pointer to descriptor buffer - */ -uint8_t *USBD_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) -{ - UNUSED(speed); - *length = sizeof(USBD_CONFIGURATION_FS_STRING); - return (uint8_t*)USBD_CONFIGURATION_FS_STRING; -} - -/** - * @brief Returns the interface string descriptor. - * @param speed: Current device speed - * @param length: Pointer to data length variable - * @retval Pointer to descriptor buffer - */ -uint8_t *USBD_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) -{ - UNUSED(speed); - *length = sizeof(USBD_INTERFACE_FS_STRING); - return (uint8_t*)USBD_INTERFACE_FS_STRING; -} - -/** -* @brief DeviceQualifierDescriptor -* return Device Qualifier descriptor -* @param length : pointer data length -* @retval pointer to descriptor buffer -*/ -uint8_t *USBD_GetDeviceQualifierDesc_impl (uint16_t *length) -{ - *length = sizeof (USBD_DeviceQualifierDesc); - return (uint8_t*)USBD_DeviceQualifierDesc; -} - -/** - * @brief USBD_CUSTOM_HID_GetCfgDesc - * return configuration descriptor - * @param speed : current device speed - * @param length : pointer data length - * @retval pointer to descriptor buffer - */ -uint8_t *USBD_GetCfgDesc_impl (uint16_t *length) -{ - *length = sizeof (N_USBD_CfgDesc); - return (uint8_t*)N_USBD_CfgDesc; -} - -uint8_t* USBD_HID_GetHidDescriptor_impl(uint16_t* len) { - switch (USBD_Device.request.wIndex&0xFF) { -#ifdef HAVE_IO_U2F - case U2F_INTF: - *len = sizeof(USBD_HID_Desc_fido); - return (uint8_t*)USBD_HID_Desc_fido; -#endif // HAVE_IO_U2F - case HID_INTF: - *len = sizeof(USBD_HID_Desc); - return (uint8_t*)USBD_HID_Desc; - } - *len = 0; - return 0; -} - -uint8_t* USBD_HID_GetReportDescriptor_impl(uint16_t* len) { - switch (USBD_Device.request.wIndex&0xFF) { -#ifdef HAVE_IO_U2F - case U2F_INTF: - - // very dirty work due to lack of callback when USB_HID_Init is called - USBD_LL_OpenEP(&USBD_Device, - U2F_EPIN_ADDR, - USBD_EP_TYPE_INTR, - U2F_EPIN_SIZE); - - USBD_LL_OpenEP(&USBD_Device, - U2F_EPOUT_ADDR, - USBD_EP_TYPE_INTR, - U2F_EPOUT_SIZE); - - /* Prepare Out endpoint to receive 1st packet */ - USBD_LL_PrepareReceive(&USBD_Device, U2F_EPOUT_ADDR, U2F_EPOUT_SIZE); - - - *len = sizeof(HID_ReportDesc_fido); - return (uint8_t*)HID_ReportDesc_fido; -#endif // HAVE_IO_U2F - case HID_INTF: - *len = sizeof(HID_ReportDesc); - return (uint8_t*)HID_ReportDesc; - } - *len = 0; - return 0; -} - -/** - * @} - */ - - -/** - * @brief USBD_HID_DataOut - * handle data OUT Stage - * @param pdev: device instance - * @param epnum: endpoint index - * @retval status - * - * This function is the default behavior for our implementation when data are sent over the out hid endpoint - */ -extern volatile unsigned short G_io_apdu_length; - -#ifdef HAVE_IO_U2F -uint8_t USBD_U2F_DataIn_impl (USBD_HandleTypeDef *pdev, - uint8_t epnum) -{ - UNUSED(pdev); - // only the data hid endpoint will receive data - switch (epnum) { - // FIDO endpoint - case (U2F_EPIN_ADDR&0x7F): - // advance the u2f sending machine state - u2f_transport_sent(&G_io_u2f, U2F_MEDIA_USB); - break; - } - return USBD_OK; -} - -uint8_t USBD_U2F_DataOut_impl (USBD_HandleTypeDef *pdev, - uint8_t epnum, uint8_t* buffer) -{ - switch (epnum) { - // FIDO endpoint - case (U2F_EPOUT_ADDR&0x7F): - USBD_LL_PrepareReceive(pdev, U2F_EPOUT_ADDR , U2F_EPOUT_SIZE); - u2f_transport_received(&G_io_u2f, buffer, io_seproxyhal_get_ep_rx_size(U2F_EPOUT_ADDR), U2F_MEDIA_USB); - break; - } - - return USBD_OK; -} -#endif // HAVE_IO_U2F - -uint8_t USBD_HID_DataOut_impl (USBD_HandleTypeDef *pdev, - uint8_t epnum, uint8_t* buffer) -{ - // only the data hid endpoint will receive data - switch (epnum) { - - // HID gen endpoint - case (HID_EPOUT_ADDR&0x7F): - // prepare receiving the next chunk (masked time) - USBD_LL_PrepareReceive(pdev, HID_EPOUT_ADDR , HID_EPOUT_SIZE); - - // avoid troubles when an apdu has not been replied yet - if (G_io_apdu_media == IO_APDU_MEDIA_NONE) { - // add to the hid transport - switch(io_usb_hid_receive(io_usb_send_apdu_data, buffer, io_seproxyhal_get_ep_rx_size(HID_EPOUT_ADDR))) { - default: - break; - - case IO_USB_APDU_RECEIVED: - G_io_apdu_media = IO_APDU_MEDIA_USB_HID; // for application code - G_io_apdu_state = APDU_USB_HID; // for next call to io_exchange - G_io_apdu_length = G_io_usb_hid_total_length; - break; - } - } - break; - } - - return USBD_OK; -} - -/** @defgroup USBD_HID_Private_Functions - * @{ - */ - -// note: how core lib usb calls the hid class -const USBD_DescriptorsTypeDef const HID_Desc = { - USBD_DeviceDescriptor, - USBD_LangIDStrDescriptor, - USBD_ManufacturerStrDescriptor, - USBD_ProductStrDescriptor, - USBD_SerialStrDescriptor, - USBD_ConfigStrDescriptor, - USBD_InterfaceStrDescriptor, - NULL, -}; - -#ifdef HAVE_IO_U2F -static const USBD_ClassTypeDef const USBD_U2F = -{ - USBD_HID_Init, - USBD_HID_DeInit, - USBD_HID_Setup, - NULL, /*EP0_TxSent*/ - NULL, /*EP0_RxReady*/ /* STATUS STAGE IN */ - USBD_U2F_DataIn_impl, /*DataIn*/ - USBD_U2F_DataOut_impl, /*DataOut*/ - NULL, /*SOF */ - NULL, - NULL, - USBD_GetCfgDesc_impl, - USBD_GetCfgDesc_impl, - USBD_GetCfgDesc_impl, - USBD_GetDeviceQualifierDesc_impl, -}; -#endif // HAVE_IO_U2F - -static const USBD_ClassTypeDef const USBD_HID = -{ - USBD_HID_Init, - USBD_HID_DeInit, - USBD_HID_Setup, - NULL, /*EP0_TxSent*/ - NULL, /*EP0_RxReady*/ /* STATUS STAGE IN */ - NULL, /*DataIn*/ - USBD_HID_DataOut_impl, /*DataOut*/ - NULL, /*SOF */ - NULL, - NULL, - USBD_GetCfgDesc_impl, - USBD_GetCfgDesc_impl, - USBD_GetCfgDesc_impl, - USBD_GetDeviceQualifierDesc_impl, -}; - -#ifdef HAVE_USB_CLASS_CCID -static const USBD_ClassTypeDef USBD_CCID = -{ - USBD_CCID_Init, - USBD_CCID_DeInit, - USBD_CCID_Setup, - NULL, /*EP0_TxSent*/ - NULL, /*EP0_RxReady*/ - USBD_CCID_DataIn, - USBD_CCID_DataOut, - NULL, /*SOF */ - NULL, /*ISOIn*/ - NULL, /*ISOOut*/ - USBD_GetCfgDesc_impl, - USBD_GetCfgDesc_impl, - USBD_GetCfgDesc_impl, - USBD_GetDeviceQualifierDesc_impl, -}; - -uint8_t SC_AnswerToReset (uint8_t voltage, uint8_t* atr_buffer) { - UNUSED(voltage); - // return the atr length - atr_buffer[0] = 0x3B; - atr_buffer[1] = 0; - return 2; -} - -void SC_Poweroff(void) { - // nothing to do ? -} - -uint8_t SC_ExecuteEscape (uint8_t* escapePtr, uint32_t escapeLen, - uint8_t* responseBuff, - uint16_t* responseLen) { - UNUSED(escapePtr); - UNUSED(escapeLen); - UNUSED(responseBuff); - UNUSED(responseLen); - // nothing to do ? - return 0; -} -#endif // HAVE_USB_CLASS_CCID - -void USB_power(unsigned char enabled) { - os_memset(&USBD_Device, 0, sizeof(USBD_Device)); - - if (enabled) { - os_memset(&USBD_Device, 0, sizeof(USBD_Device)); - /* Init Device Library */ - USBD_Init(&USBD_Device, (USBD_DescriptorsTypeDef*)&HID_Desc, 0); - - /* Register the HID class */ - USBD_RegisterClassForInterface(HID_INTF, &USBD_Device, (USBD_ClassTypeDef*)&USBD_HID); -#ifdef HAVE_IO_U2F - USBD_RegisterClassForInterface(U2F_INTF, &USBD_Device, (USBD_ClassTypeDef*)&USBD_U2F); - // initialize the U2F tunnel transport - u2f_transport_init(&G_io_u2f, G_io_apdu_buffer, IO_APDU_BUFFER_SIZE); -#endif // HAVE_IO_U2F -#ifdef HAVE_USB_CLASS_CCID - USBD_RegisterClassForInterface(CCID_INTF, &USBD_Device, (USBD_ClassTypeDef*)&USBD_CCID); -#endif // HAVE_USB_CLASS_CCID - - - /* Start Device Process */ - USBD_Start(&USBD_Device); - } - else { - USBD_DeInit(&USBD_Device); - } -} - -/** - * @} - */ - - -/** - * @} - */ - - -/** - * @} - */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/src/sdk/usbd_impl.h b/src/sdk/usbd_impl.h deleted file mode 100644 index a20edef..0000000 --- a/src/sdk/usbd_impl.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef USBD_IMPL_H -#define USBD_IMPL_H - - -uint8_t *USBD_GetCfgDesc_impl (uint16_t *length); - -#endif //USBD_IMPL_H \ No newline at end of file diff --git a/src/usbd_ccid_impl.c b/src/usbd_ccid_impl.c new file mode 100644 index 0000000..2a54750 --- /dev/null +++ b/src/usbd_ccid_impl.c @@ -0,0 +1,463 @@ +/** + ****************************************************************************** + * @file usbd_ccid_core.c + * @author MCD Application Team + * @version V1.0.1 + * @date 31-January-2014 + * @brief This file provides all the CCID core functions. + * + * @verbatim + * + * =================================================================== + * CCID Class Description + * =================================================================== + * This module manages the Specification for Integrated Circuit(s) + * Cards Interface Revision 1.1 + * This driver implements the following aspects of the specification: + * - Bulk Transfers + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ccid_core.h" + +#ifdef HAVE_USB_CLASS_CCID + +#define USBD_LANGID_STRING 0x409 + +#define USBD_VID 0x2C97 +#if TARGET_ID == 0x31000002 // blue +#define USBD_PID 0x0000 +static const uint8_t const USBD_PRODUCT_FS_STRING[] = { + 4*2+2, + USB_DESC_TYPE_STRING, + 'B', 0, + 'l', 0, + 'u', 0, + 'e', 0, +}; + +#elif TARGET_ID == 0x31100002 // nano s +#define USBD_PID 0x0001 +static const uint8_t const USBD_PRODUCT_FS_STRING[] = { + 6*2+2, + USB_DESC_TYPE_STRING, + 'N', 0, + 'a', 0, + 'n', 0, + 'o', 0, + ' ', 0, + 'S', 0, +}; +#elif TARGET_ID == 0x31200002 // aramis +#define USBD_PID 0x0002 +static const uint8_t const USBD_PRODUCT_FS_STRING[] = { + 6*2+2, + USB_DESC_TYPE_STRING, + 'A', 0, + 'r', 0, + 'a', 0, + 'm', 0, + 'i', 0, + 's', 0, +}; +#else +#error unknown TARGET_ID +#endif + + +/* USB Standard Device Descriptor */ +static __ALIGN_BEGIN const uint8_t const USBD_DeviceQualifierDesc[] __ALIGN_END = +{ + USB_LEN_DEV_QUALIFIER_DESC, + USB_DESC_TYPE_DEVICE_QUALIFIER, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + 0x40, + 0x01, + 0x00, +}; + +/* USB Standard Device Descriptor */ +static const uint8_t const USBD_LangIDDesc[]= +{ + USB_LEN_LANGID_STR_DESC, + USB_DESC_TYPE_STRING, + LOBYTE(USBD_LANGID_STRING), + HIBYTE(USBD_LANGID_STRING), +}; + +static const uint8_t const USB_SERIAL_STRING[] = +{ + 4*2+2, + USB_DESC_TYPE_STRING, + '0', 0, + '0', 0, + '0', 0, + '1', 0, +}; + +static const uint8_t const USBD_MANUFACTURER_STRING[] = { + 6*2+2, + USB_DESC_TYPE_STRING, + 'L', 0, + 'e', 0, + 'd', 0, + 'g', 0, + 'e', 0, + 'r', 0, +}; + +#define USBD_INTERFACE_FS_STRING USBD_PRODUCT_FS_STRING +#define USBD_CONFIGURATION_FS_STRING USBD_PRODUCT_FS_STRING + + +/* USB Standard Device Descriptor */ +static const uint8_t const USBD_DeviceDesc[]= { + 0x12, /* bLength */ + USB_DESC_TYPE_DEVICE, /* bDescriptorType */ + 0x00, /* bcdUSB */ + 0x02, + 0x00, /* bDeviceClass */ + 0x00, /* bDeviceSubClass */ + 0x00, /* bDeviceProtocol */ + USB_MAX_EP0_SIZE, /* bMaxPacketSize */ + LOBYTE(USBD_VID), /* idVendor */ + HIBYTE(USBD_VID), /* idVendor */ + LOBYTE(USBD_PID), /* idVendor */ + HIBYTE(USBD_PID), /* idVendor */ + 0x00, /* bcdDevice rel. 2.00 */ + 0x02, + USBD_IDX_MFC_STR, /* Index of manufacturer string */ + USBD_IDX_PRODUCT_STR, /* Index of product string */ + USBD_IDX_SERIAL_STR, /* Index of serial number string */ + USBD_MAX_NUM_CONFIGURATION /* bNumConfigurations */ +}; /* USB_DeviceDescriptor */ + + +/* USB Mass storage device Configuration Descriptor */ +/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */ +#define USBD_OFFSET_CfgDesc_bPINSupport 70 +const uint8_t N_USBD_CfgDesc[] = +{ + + 0x09, /* bLength: Configuration Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + 0x9+0x9+0x36+0x7+0x7+0x7, + + 0x00, + 0x01, /* bNumInterfaces: 1 interface */ + 0x01, /* bConfigurationValue: */ + 0x04, /* iConfiguration: */ + 0x80, /*bmAttributes: bus powered */ + 0x32, /* MaxPower 100 mA */ + + /******************** CCID **** interface ********************/ + 0x09, /* bLength: Interface Descriptor size */ + 0x04, /* bDescriptorType: */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x03, /* bNumEndpoints: 3 endpoints used */ + 0x0B, /* bInterfaceClass: user's interface for CCID */ + 0x00, /* bInterfaceSubClass : */ + 0x00, /* nInterfaceProtocol : None */ + 0x05, /* iInterface: */ + + /******************* CCID class descriptor ********************/ + 0x36, /* bLength: CCID Descriptor size */ + 0x21, /* bDescriptorType: Functional Descriptor type. */ + 0x10, /* bcdCCID(LSB): CCID Class Spec release number (1.00) */ + 0x01, /* bcdCCID(MSB) */ + + 0x00, /* bMaxSlotIndex :highest available slot on this device */ + 0x03, /* bVoltageSupport: bit Wise OR for 01h-5.0V 02h-3.0V + 04h 1.8V*/ + + 0x01,0x00,0x00,0x00, /* dwProtocols: 0001h = Protocol T=0 */ + 0x10,0x0E,0x00,0x00, /* dwDefaultClock: 3.6Mhz = 3600kHz = 0x0E10, + for 4 Mhz the value is (0x00000FA0) : + This is used in ETU and waiting time calculations*/ + 0x10,0x0E,0x00,0x00, /* dwMaximumClock: Maximum supported ICC clock frequency + in KHz. So, 3.6Mhz = 3600kHz = 0x0E10, + 4 Mhz (0x00000FA0) : */ + 0x00, /* bNumClockSupported : no setting from PC + If the value is 00h, the + supported clock frequencies are assumed to be the + default clock frequency defined by dwDefaultClock + and the maximum clock frequency defined by + dwMaximumClock */ + + 0xCD,0x25,0x00,0x00, /* dwDataRate: Default ICC I/O data rate in bps + 9677 bps = 0x25CD + for example 10752 bps (0x00002A00) */ + + 0xCD,0x25,0x00,0x00, /* dwMaxDataRate: Maximum supported ICC I/O data + rate in bps */ + 0x00, /* bNumDataRatesSupported : + The number of data rates that are supported by the CCID + If the value is 00h, all data rates between the default + data rate dwDataRate and the maximum data rate + dwMaxDataRate are supported. + Dont support GET_CLOCK_FREQUENCIES + */ + //46 + 0x00,0x00,0x00,0x00, /* dwMaxIFSD: 0 (T=0 only) */ + 0x00,0x00,0x00,0x00, /* dwSynchProtocols */ + 0x00,0x00,0x00,0x00, /* dwMechanical: no special characteristics */ + + 0x38,0x00,EXCHANGE_LEVEL_FEATURE,0x00, + /* dwFeatures: clk, baud rate, voltage : automatic */ + /* 00000008h Automatic ICC voltage selection + 00000010h Automatic ICC clock frequency change + 00000020h Automatic baud rate change according to + active parameters provided by the Host or self + determined 00000100h CCID can set + ICC in clock stop mode + + Only one of the following values may be present to + select a level of exchange: + 00010000h TPDU level exchanges with CCID + 00020000h Short APDU level exchange with CCID + 00040000h Short and Extended APDU level exchange + If none of those values : character level of exchange*/ + #if 1 + 0x0F,0x01,0x00,0x00, /* dwMaxCCIDMessageLength: Maximum block size + header*/ + /* 261 + 10 */ + #else + 0xF8,0x00,0x00,0x00, /* dwMaxCCIDMessageLength: Maximum block size + header*/ + /* EEh + 10 */ + #endif + 0x00, /* bClassGetResponse*/ + 0x00, /* bClassEnvelope */ + 0x00,0x00, /* wLcdLayout : 0000h no LCD. */ + 0x03, /* bPINSupport : no PIN verif and modif */ //<= offset: 70 + 0x01, /* bMaxCCIDBusySlots */ + + //72 + /******************** CCID Endpoints ********************/ + 0x07, /*Endpoint descriptor length = 7*/ + 0x05, /*Endpoint descriptor type */ + CCID_BULK_IN_EP, /*Endpoint address (IN, address 1) */ + 0x02, /*Bulk endpoint type */ + LOBYTE(CCID_BULK_EPIN_SIZE), + HIBYTE(CCID_BULK_EPIN_SIZE), + 0x00, /*Polling interval in milliseconds */ + + 0x07, /*Endpoint descriptor length = 7 */ + 0x05, /*Endpoint descriptor type */ + CCID_BULK_OUT_EP, /*Endpoint address (OUT, address 1) */ + 0x02, /*Bulk endpoint type */ + LOBYTE(CCID_BULK_EPOUT_SIZE), + HIBYTE(CCID_BULK_EPOUT_SIZE), + 0x00, /*Polling interval in milliseconds*/ + + + 0x07, /*bLength: Endpoint Descriptor size*/ + 0x05, /*bDescriptorType:*/ + CCID_INTR_IN_EP, /*bEndpointAddress: Endpoint Address (IN)*/ + 0x03, /* bmAttributes: Interrupt endpoint */ + LOBYTE(CCID_INTR_EPIN_SIZE), + HIBYTE(CCID_INTR_EPIN_SIZE), + 0x18 /*Polling interval in milliseconds */ +}; + + + +static uint8_t *USBD_GetCfgDesc_impl (uint16_t *length) +{ + *length = sizeof (N_USBD_CfgDesc); + return (uint8_t*)(N_USBD_CfgDesc); +} + +/** + * @brief Returns the device descriptor. + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +static uint8_t *USBD_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + UNUSED(speed); + *length = sizeof(USBD_DeviceDesc); + return (uint8_t*)USBD_DeviceDesc; +} + +/** + * @brief Returns the LangID string descriptor. + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +static uint8_t *USBD_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + UNUSED(speed); + *length = sizeof(USBD_LangIDDesc); + return (uint8_t*)USBD_LangIDDesc; +} + +/** + * @brief Returns the product string descriptor. + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +static uint8_t *USBD_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + UNUSED(speed); + *length = sizeof(USBD_PRODUCT_FS_STRING); + return (uint8_t*)USBD_PRODUCT_FS_STRING; +} + +/** + * @brief Returns the manufacturer string descriptor. + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +static uint8_t *USBD_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + UNUSED(speed); + *length = sizeof(USBD_MANUFACTURER_STRING); + return (uint8_t*)USBD_MANUFACTURER_STRING; +} + +/** + * @brief Returns the serial number string descriptor. + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +static uint8_t *USBD_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + UNUSED(speed); + *length = sizeof(USB_SERIAL_STRING); + return (uint8_t*)USB_SERIAL_STRING; +} + +/** + * @brief Returns the configuration string descriptor. + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +static uint8_t *USBD_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + UNUSED(speed); + *length = sizeof(USBD_CONFIGURATION_FS_STRING); + return (uint8_t*)USBD_CONFIGURATION_FS_STRING; +} + +/** + * @brief Returns the interface string descriptor. + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +static uint8_t *USBD_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + UNUSED(speed); + *length = sizeof(USBD_INTERFACE_FS_STRING); + return (uint8_t*)USBD_INTERFACE_FS_STRING; +} + +/** +* @brief DeviceQualifierDescriptor +* return Device Qualifier descriptor +* @param length : pointer data length +* @retval pointer to descriptor buffer +*/ +static uint8_t *USBD_GetDeviceQualifierDesc_impl (uint16_t *length) +{ + *length = sizeof (USBD_DeviceQualifierDesc); + return (uint8_t*)USBD_DeviceQualifierDesc; +} + + +uint8_t SC_AnswerToReset (uint8_t voltage, uint8_t* atr_buffer) { + // return the atr length + atr_buffer[0] = 0x3B; + atr_buffer[1] = 0; + return 2; +} + + +// note: how core lib usb calls the hid class +static const USBD_DescriptorsTypeDef const CCID_Desc = { + USBD_DeviceDescriptor, + USBD_LangIDStrDescriptor, + USBD_ManufacturerStrDescriptor, + USBD_ProductStrDescriptor, + USBD_SerialStrDescriptor, + USBD_ConfigStrDescriptor, + USBD_InterfaceStrDescriptor, + NULL, +}; + +static const USBD_ClassTypeDef USBD_CCID = +{ + USBD_CCID_Init, + USBD_CCID_DeInit, + USBD_CCID_Setup, + NULL, /*EP0_TxSent*/ + NULL, /*EP0_RxReady*/ + USBD_CCID_DataIn, + USBD_CCID_DataOut, + NULL, /*SOF */ + NULL, /*ISOIn*/ + NULL, /*ISOOut*/ + USBD_GetCfgDesc_impl, + USBD_GetCfgDesc_impl, + USBD_GetCfgDesc_impl, + USBD_GetDeviceQualifierDesc_impl, +}; + + +void USBD_CCID_activate_pinpad(int enabled) { + unsigned char e; + e = enabled?3:0; + nvm_write(((char*)PIC(N_USBD_CfgDesc))+USBD_OFFSET_CfgDesc_bPINSupport, &e,1); +} + +void USB_CCID_power(unsigned char enabled) { + os_memset(&USBD_Device, 0, sizeof(USBD_Device)); + + if (enabled) { + os_memset(&USBD_Device, 0, sizeof(USBD_Device)); + /* Init Device Library */ + USBD_Init(&USBD_Device, (USBD_DescriptorsTypeDef*)&CCID_Desc, 0); + + /* Register the HID class */ + USBD_RegisterClass(&USBD_Device, (USBD_ClassTypeDef*)&USBD_CCID); + + /* Start Device Process */ + USBD_Start(&USBD_Device); + } + else { + USBD_DeInit(&USBD_Device); + } +} + +#endif // HAVE_USB_CLASS_CCID diff --git a/src/usbd_ccid_impl.h b/src/usbd_ccid_impl.h new file mode 100644 index 0000000..b254b71 --- /dev/null +++ b/src/usbd_ccid_impl.h @@ -0,0 +1,24 @@ +#ifndef USBD_CCID_IMPL_H +#define USBD_CCID_IMPL_H + +#define TPDU_EXCHANGE 0x01 +#define SHORT_APDU_EXCHANGE 0x02 +#define EXTENDED_APDU_EXCHANGE 0x04 +#define CHARACTER_EXCHANGE 0x00 + +#define EXCHANGE_LEVEL_FEATURE SHORT_APDU_EXCHANGE + + +#define CCID_BULK_IN_EP 0x82 +#define CCID_BULK_EPIN_SIZE 64 +#define CCID_BULK_OUT_EP 0x02 +#define CCID_BULK_EPOUT_SIZE 64 +#define CCID_INTR_IN_EP 0x81 +#define CCID_INTR_EPIN_SIZE 16 + +#define CCID_EP0_BUFF_SIZ 64 + +void USB_CCID_power(unsigned char enabled); +void USBD_CCID_activate_pinpad(int enabled); + +#endif // USBD_CCID_IMPL_H \ No newline at end of file