1 /******************************************************************************
2  *
3  *  Copyright (C) 2018 ST Microelectronics S.A.
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  *
18  ******************************************************************************/
19 #include "CommandApdu.h"
20 #include <string.h>
21 
22 /*******************************************************************************
23 **
24 ** Function        CommandApdu_toByteArray
25 **
26 ** Description     Transforms a CommandApdu into a byte array.
27 **
28 ** Parameters      cmdApdu          - input APDU struct.
29 **                 commandApduArray - output array bytes.
30 **
31 ** Returns         CommandApduArray size.
32 **
33 *******************************************************************************/
CommandApdu_toByteArray(CommandApdu cmdApdu,char * commandApduArray)34 int CommandApdu_toByteArray(CommandApdu cmdApdu, char* commandApduArray) {
35   int commandApduArraySize = CommandApdu_getSize(cmdApdu);
36 
37   if (cmdApdu.lc > MAX_CMD_APDU_DATA_LENGTH) {
38     return -1;
39   }
40 
41   commandApduArray[0] = cmdApdu.cla;
42   commandApduArray[1] = cmdApdu.ins;
43   commandApduArray[2] = cmdApdu.p1;
44   commandApduArray[3] = cmdApdu.p2;
45 
46   if (cmdApdu.lc > 0) {
47     commandApduArray[4] = cmdApdu.lc;
48     memcpy(commandApduArray + 5, cmdApdu.data, cmdApdu.lc);
49   }
50 
51   if (cmdApdu.le >= 0) {
52     commandApduArray[commandApduArraySize - 1] = cmdApdu.le;
53   }
54 
55   return commandApduArraySize;
56 }
57 
58 /*******************************************************************************
59 **
60 ** Function        CommandApdu_getSize
61 **
62 ** Description     Get the size of a CommandApdu structure
63 **
64 ** Parameters      cmdApdu          - input APDU struct.
65 **
66 ** Returns         cmdApdu size.
67 **
68 *******************************************************************************/
CommandApdu_getSize(CommandApdu cmdApdu)69 int CommandApdu_getSize(CommandApdu cmdApdu) {
70   // There will be always cla+ins+p1+p2
71   int size = 4;
72 
73   if (cmdApdu.lc > 0) {
74     // Size of lc + data
75     size += 1 + cmdApdu.lc;
76   }
77 
78   if (cmdApdu.le >= 0) {
79     size++;
80   }
81 
82   return size;
83 }
84 
85 /*******************************************************************************
86 **
87 ** Function        CommandApdu_formApduType4
88 **
89 ** Description     Forms an APDU
90 **
91 ** Parameters
92 **
93 ** Returns         -1 if error 0 if ok
94 **
95 *******************************************************************************/
CommandApdu_formApduType4(char cla,char ins,char p1,char p2,char lc,char * cmdData,char le,CommandApdu * cmdApdu)96 int CommandApdu_formApduType4(char cla, char ins, char p1, char p2, char lc,
97                               char* cmdData, char le, CommandApdu* cmdApdu) {
98   if (lc > MAX_CMD_APDU_DATA_LENGTH) {
99     return -1;
100   }
101 
102   cmdApdu->cla = cla;
103   cmdApdu->ins = ins;
104   cmdApdu->p1 = p1;
105   cmdApdu->p2 = p2;
106   cmdApdu->lc = lc;
107   if (lc > 0) {
108     memcpy(cmdApdu->data, cmdData, lc);
109   }
110   cmdApdu->le = le;
111 
112   return CommandApdu_getSize(*cmdApdu);
113 }
114 
115 /*******************************************************************************
116 **
117 ** Function        CommandApdu_formApduType2
118 **
119 ** Description     Forms an APDU
120 **
121 ** Parameters
122 **
123 ** Returns         -1 if error 0 if ok
124 **
125 *******************************************************************************/
CommandApdu_formApduType2(char cla,char ins,char p1,char p2,char le,CommandApdu * cmdApdu)126 int CommandApdu_formApduType2(char cla, char ins, char p1, char p2, char le,
127                               CommandApdu* cmdApdu) {
128   cmdApdu->cla = cla;
129   cmdApdu->ins = ins;
130   cmdApdu->p1 = p1;
131   cmdApdu->p2 = p2;
132   cmdApdu->le = le;
133   cmdApdu->lc = 0;
134 
135   return CommandApdu_getSize(*cmdApdu);
136 }
137