1.1.0 fixes
Fix PIN management PINPAD CCID command was in conflict with new PIN get status APDU. Use class CLA=0xEF to differenciate both case. Fix Terminate status management Fix RC code setting Add MSE support Set MSE supported in capabilities
This commit is contained in:
parent
38e143d248
commit
cf6e295e47
11 changed files with 128 additions and 35 deletions
|
@ -654,10 +654,27 @@ int gpg_apdu_put_data(unsigned int ref) {
|
|||
}
|
||||
|
||||
/* ----------------- RC ----------------- */
|
||||
case 0xD3:
|
||||
sw = gpg_apdu_change_ref_data();
|
||||
break;
|
||||
case 0xD3: {
|
||||
gpg_pin_t *pin;
|
||||
|
||||
pin = gpg_pin_get_pin(PIN_ID_RC);
|
||||
if (G_gpg_vstate.io_length == 0) {
|
||||
gpg_nvm_write(pin, NULL, sizeof(gpg_pin_t));
|
||||
|
||||
}
|
||||
else if ((G_gpg_vstate.io_length > GPG_MAX_PW_LENGTH) ||
|
||||
(G_gpg_vstate.io_length < 8)) {
|
||||
THROW(SW_WRONG_DATA);
|
||||
return SW_WRONG_DATA;
|
||||
} else {
|
||||
gpg_pin_set(pin,
|
||||
G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset,
|
||||
G_gpg_vstate.io_length);
|
||||
}
|
||||
sw = SW_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
/* ----------------- UIF ----------------- */
|
||||
case 0xD6:
|
||||
ptr_v = G_gpg_vstate.kslot->sig.UIF;
|
||||
|
|
|
@ -236,7 +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)) {
|
||||
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;
|
||||
}
|
||||
|
@ -271,7 +271,6 @@ int gpg_dispatch() {
|
|||
}
|
||||
|
||||
|
||||
|
||||
/* Other commands allowed if not terminated */
|
||||
if (N_gpg_pstate->histo[7] != 0x07) {
|
||||
THROW(SW_STATE_TERMINATED);
|
||||
|
|
|
@ -92,7 +92,7 @@ int gpg_oid2curve(unsigned char* oid, unsigned int len) {
|
|||
/* -------------------------------*/
|
||||
|
||||
const unsigned char C_ext_capabilities[10] = {
|
||||
//-SM, +getchallenge, +keyimport, +PWchangeable, +privateDO, +algAttrChangeable, +AES, -RFU
|
||||
//-SM, +getchallenge, +keyimport, +PWchangeable, +privateDO, +algAttrChangeable, +AES, -KDF
|
||||
0x7E,
|
||||
// No SM,
|
||||
0x00,
|
||||
|
@ -104,8 +104,8 @@ const unsigned char C_ext_capabilities[10] = {
|
|||
SHORT(GPG_EXT_PRIVATE_DO_LENGTH),
|
||||
//PIN block formart 2 not supported
|
||||
0x00,
|
||||
//RFU
|
||||
0x00
|
||||
//MSE
|
||||
0x01
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -247,7 +247,7 @@ int gpg_io_fetch(unsigned char* buffer, int len) {
|
|||
int gpg_io_do(unsigned int io_flags) {
|
||||
|
||||
//if pending input chaining
|
||||
if (G_gpg_vstate.io_cla & 0x01) {
|
||||
if (G_gpg_vstate.io_cla & 0x10) {
|
||||
goto in_chaining;
|
||||
}
|
||||
|
||||
|
|
78
src/gpg_mse.c
Normal file
78
src/gpg_mse.c
Normal file
|
@ -0,0 +1,78 @@
|
|||
/* Copyright 2017 Cedric Mesnil <cslashm@gmail.com>, 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.
|
||||
*/
|
||||
|
||||
#include "os.h"
|
||||
#include "cx.h"
|
||||
#include "gpg_types.h"
|
||||
#include "gpg_api.h"
|
||||
#include "gpg_vars.h"
|
||||
|
||||
static int gpg_mse_set(int crt, int ref) {
|
||||
|
||||
if (crt == 0xA4) {
|
||||
if (ref == 0x02) {
|
||||
G_gpg_vstate.mse_aut = &G_gpg_vstate.kslot->dec;
|
||||
}
|
||||
if (ref == 0x03) {
|
||||
G_gpg_vstate.mse_aut = &G_gpg_vstate.kslot->aut;
|
||||
}
|
||||
}
|
||||
|
||||
if (crt == 0xB8) {
|
||||
if (ref == 0x02) {
|
||||
G_gpg_vstate.mse_dec = &G_gpg_vstate.kslot->dec;
|
||||
}
|
||||
if (ref == 0x03) {
|
||||
G_gpg_vstate.mse_dec = &G_gpg_vstate.kslot->aut;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int gpg_mse_reset() {
|
||||
gpg_mse_set(0xA4, 0x03);
|
||||
gpg_mse_set(0xB8, 0x02);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gpg_apdu_mse() {
|
||||
int crt,ref;
|
||||
|
||||
|
||||
if ((G_gpg_vstate.io_p1 != 0x41) ||
|
||||
((G_gpg_vstate.io_p2 != 0xA4)&&(G_gpg_vstate.io_p2 != 0xB8))) {
|
||||
THROW(SW_INCORRECT_P1P2);
|
||||
return SW_INCORRECT_P1P2;
|
||||
}
|
||||
|
||||
crt = gpg_io_fetch_u16();
|
||||
if (crt != 0x8301) {
|
||||
THROW(SW_WRONG_DATA);
|
||||
return SW_WRONG_DATA;
|
||||
}
|
||||
|
||||
ref = gpg_io_fetch_u8();
|
||||
if ((ref != 0x02) && (ref != 0x03)) {
|
||||
THROW(SW_WRONG_DATA);
|
||||
return SW_WRONG_DATA;
|
||||
}
|
||||
|
||||
gpg_mse_set(crt,ref);
|
||||
gpg_io_discard(1);
|
||||
return SW_OK;
|
||||
|
||||
}
|
|
@ -83,6 +83,7 @@ static void gpg_pin_check_throw(gpg_pin_t *pin, int pinID,
|
|||
return;
|
||||
}
|
||||
THROW(sw);
|
||||
return;
|
||||
}
|
||||
|
||||
int gpg_pin_check(gpg_pin_t *pin, int pinID,
|
||||
|
@ -143,10 +144,8 @@ int gpg_apdu_verify() {
|
|||
return SW_WRONG_DATA;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//PINPAD
|
||||
if (G_gpg_vstate.io_cla==0xFF) {
|
||||
//PINPAD
|
||||
if (G_gpg_vstate.io_cla == 0xEF) {
|
||||
if (gpg_pin_is_blocked(pin)) {
|
||||
THROW(SW_PIN_BLOCKED);
|
||||
return SW_PIN_BLOCKED;
|
||||
|
@ -220,25 +219,7 @@ int gpg_apdu_change_ref_data() {
|
|||
gpg_pin_set_verified(pin->ref,0);
|
||||
|
||||
|
||||
// --- RC pin ---
|
||||
if (pin->ref == PIN_ID_RC) {
|
||||
newlen = G_gpg_vstate.io_length;
|
||||
if (newlen == 0) {
|
||||
gpg_nvm_write(pin, NULL, sizeof(gpg_pin_t));
|
||||
|
||||
}
|
||||
else if ((newlen > GPG_MAX_PW_LENGTH) ||
|
||||
(newlen < 8)) {
|
||||
THROW(SW_WRONG_DATA);
|
||||
return SW_WRONG_DATA;
|
||||
} else {
|
||||
gpg_pin_set(pin,
|
||||
G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset,
|
||||
newlen);
|
||||
}
|
||||
gpg_io_discard(1);
|
||||
return SW_OK;
|
||||
}
|
||||
|
||||
|
||||
// --- PW1/PW3 pin ---
|
||||
if (gpg_pin_is_blocked(pin)) {
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#ifndef GPG_DEBUG_MAIN
|
||||
unsigned char G_io_seproxyhal_spi_buffer[IO_SEPROXYHAL_BUFFER_SIZE_B];
|
||||
ux_state_t ux;
|
||||
|
||||
#else
|
||||
extern unsigned char G_io_seproxyhal_spi_buffer[IO_SEPROXYHAL_BUFFER_SIZE_B];
|
||||
int apdu_n;
|
||||
|
|
|
@ -36,6 +36,9 @@ int gpg_apdu_select() {
|
|||
}
|
||||
|
||||
gpg_io_discard(0);
|
||||
if (N_gpg_pstate->histo[7] != 0x07) {
|
||||
THROW(SW_STATE_TERMINATED);
|
||||
}
|
||||
sw = SW_OK;
|
||||
} else {
|
||||
THROW(SW_FILE_NOT_FOUND);
|
||||
|
|
|
@ -179,6 +179,7 @@ struct gpg_v_state_s {
|
|||
unsigned char seed_mode;
|
||||
|
||||
/* io state*/
|
||||
|
||||
unsigned char io_cla;
|
||||
unsigned char io_ins;
|
||||
unsigned char io_p1;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue