|
Packit |
9f0df5 |
/*
|
|
Packit |
9f0df5 |
pps.c
|
|
Packit |
9f0df5 |
Protocol Parameters Selection
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
This file is part of the Unix driver for Towitoko smartcard readers
|
|
Packit |
9f0df5 |
Copyright (C) 2000 2001 Carlos Prados <cprados@yahoo.com>
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
This library is free software; you can redistribute it and/or
|
|
Packit |
9f0df5 |
modify it under the terms of the GNU Lesser General Public
|
|
Packit |
9f0df5 |
License as published by the Free Software Foundation; either
|
|
Packit |
9f0df5 |
version 2 of the License, or (at your option) any later version.
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
This library is distributed in the hope that it will be useful,
|
|
Packit |
9f0df5 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
9f0df5 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
9f0df5 |
Lesser General Public License for more details.
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
You should have received a copy of the GNU Lesser General Public License
|
|
Packit |
9f0df5 |
along with this library; if not, write to the Free Software Foundation,
|
|
Packit |
9f0df5 |
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
Packit |
9f0df5 |
*/
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
#include "pps.h"
|
|
Packit |
9f0df5 |
#include "atr.h"
|
|
Packit |
9f0df5 |
#ifdef HAVE_STDLIB_H
|
|
Packit |
9f0df5 |
#include <stdlib.h>
|
|
Packit |
9f0df5 |
#endif
|
|
Packit |
9f0df5 |
#ifdef HAVE_STRING_H
|
|
Packit |
9f0df5 |
#include <string.h>
|
|
Packit |
9f0df5 |
#endif
|
|
Packit |
9f0df5 |
#include <ifdhandler.h>
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
#include "commands.h"
|
|
Packit |
9f0df5 |
#include "defs.h"
|
|
Packit |
9f0df5 |
#include "debug.h"
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
/*
|
|
Packit |
9f0df5 |
* Not exported funtions declaration
|
|
Packit |
9f0df5 |
*/
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
static bool PPS_Match (BYTE * request, unsigned len_request, BYTE * reply, unsigned len_reply);
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
static unsigned PPS_GetLength (BYTE * block);
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
static BYTE PPS_GetPCK (BYTE * block, unsigned length);
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
int
|
|
Packit |
9f0df5 |
PPS_Exchange (int lun, BYTE * params, unsigned *length, unsigned char *pps1)
|
|
Packit |
9f0df5 |
{
|
|
Packit |
9f0df5 |
BYTE confirm[PPS_MAX_LENGTH];
|
|
Packit |
9f0df5 |
unsigned len_request, len_confirm;
|
|
Packit |
9f0df5 |
int ret;
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
len_request = PPS_GetLength (params);
|
|
Packit |
9f0df5 |
params[len_request - 1] = PPS_GetPCK(params, len_request - 1);
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
DEBUG_XXD ("PPS: Sending request: ", params, len_request);
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
/* Send PPS request */
|
|
Packit |
9f0df5 |
if (CCID_Transmit (lun, len_request, params, isCharLevel(lun) ? 4 : 0, 0)
|
|
Packit |
9f0df5 |
!= IFD_SUCCESS)
|
|
Packit |
9f0df5 |
return PPS_ICC_ERROR;
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
/* Get PPS confirm */
|
|
Packit |
9f0df5 |
len_confirm = sizeof(confirm);
|
|
Packit |
9f0df5 |
if (CCID_Receive (lun, &len_confirm, confirm, NULL) != IFD_SUCCESS)
|
|
Packit |
9f0df5 |
return PPS_ICC_ERROR;
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
DEBUG_XXD ("PPS: Receiving confirm: ", confirm, len_confirm);
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
if (!PPS_Match (params, len_request, confirm, len_confirm))
|
|
Packit |
9f0df5 |
ret = PPS_HANDSAKE_ERROR;
|
|
Packit |
9f0df5 |
else
|
|
Packit |
9f0df5 |
ret = PPS_OK;
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
*pps1 = 0x11; /* default TA1 */
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
/* if PPS1 is echoed */
|
|
Packit |
9f0df5 |
if (PPS_HAS_PPS1 (params) && PPS_HAS_PPS1 (confirm))
|
|
Packit |
9f0df5 |
*pps1 = confirm[2];
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
/* Copy PPS handsake */
|
|
Packit |
9f0df5 |
memcpy (params, confirm, len_confirm);
|
|
Packit |
9f0df5 |
(*length) = len_confirm;
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
return ret;
|
|
Packit |
9f0df5 |
}
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
static bool
|
|
Packit |
9f0df5 |
PPS_Match (BYTE * request, unsigned len_request, BYTE * confirm, unsigned len_confirm)
|
|
Packit |
9f0df5 |
{
|
|
Packit |
9f0df5 |
/* See if the reply differs from request */
|
|
Packit |
9f0df5 |
if ((len_request == len_confirm) && /* same length */
|
|
Packit |
9f0df5 |
memcmp (request, confirm, len_request)) /* different contents */
|
|
Packit |
9f0df5 |
return FALSE;
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
if (len_request < len_confirm) /* confirm longer than request */
|
|
Packit |
9f0df5 |
return FALSE;
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
/* See if the card specifies other than default FI and D */
|
|
Packit |
9f0df5 |
if ((PPS_HAS_PPS1 (confirm)) && (confirm[2] != request[2]))
|
|
Packit |
9f0df5 |
return FALSE;
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
return TRUE;
|
|
Packit |
9f0df5 |
}
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
static unsigned
|
|
Packit |
9f0df5 |
PPS_GetLength (BYTE * block)
|
|
Packit |
9f0df5 |
{
|
|
Packit |
9f0df5 |
unsigned length = 3;
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
if (PPS_HAS_PPS1 (block))
|
|
Packit |
9f0df5 |
length++;
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
if (PPS_HAS_PPS2 (block))
|
|
Packit |
9f0df5 |
length++;
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
if (PPS_HAS_PPS3 (block))
|
|
Packit |
9f0df5 |
length++;
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
return length;
|
|
Packit |
9f0df5 |
}
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
static BYTE
|
|
Packit |
9f0df5 |
PPS_GetPCK (BYTE * block, unsigned length)
|
|
Packit |
9f0df5 |
{
|
|
Packit |
9f0df5 |
BYTE pck;
|
|
Packit |
9f0df5 |
unsigned i;
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
pck = block[0];
|
|
Packit |
9f0df5 |
for (i = 1; i < length; i++)
|
|
Packit |
9f0df5 |
pck ^= block[i];
|
|
Packit |
9f0df5 |
|
|
Packit |
9f0df5 |
return pck;
|
|
Packit |
9f0df5 |
}
|
|
Packit |
9f0df5 |
|