1 #define MODULE_LOG_PREFIX "aes"
5 #include "oscam-garbage.h"
6 #include "oscam-string.h"
8 void aes_set_key(struct aes_keys
*aes
, char *key
)
10 AES_set_decrypt_key((const uint8_t *)key
, 128, &aes
->aeskey_decrypt
);
11 AES_set_encrypt_key((const uint8_t *)key
, 128, &aes
->aeskey_encrypt
);
14 bool aes_set_key_alloc(struct aes_keys
**aes
, char *key
)
16 if (!cs_malloc(aes
, sizeof(struct aes_keys
)))
20 aes_set_key(*aes
, key
);
24 void aes_decrypt(struct aes_keys
*aes
, uint8_t *buf
, int32_t n
)
27 for(i
= 0; i
< n
; i
+= 16)
29 AES_decrypt(buf
+ i
, buf
+ i
, &aes
->aeskey_decrypt
);
33 void aes_encrypt_idx(struct aes_keys
*aes
, uint8_t *buf
, int32_t n
)
36 for(i
= 0; i
< n
; i
+= 16)
38 AES_encrypt(buf
+ i
, buf
+ i
, &aes
->aeskey_encrypt
);
42 void aes_cbc_encrypt(struct aes_keys
*aes
, uint8_t *buf
, int32_t n
, uint8_t *iv
)
44 AES_cbc_encrypt(buf
, buf
, n
, &aes
->aeskey_encrypt
, iv
, AES_ENCRYPT
);
47 void aes_cbc_decrypt(struct aes_keys
*aes
, uint8_t *buf
, int32_t n
, uint8_t *iv
)
49 AES_cbc_encrypt(buf
, buf
, n
, &aes
->aeskey_decrypt
, iv
, AES_DECRYPT
);
52 /* Creates an AES_ENTRY and adds it to the given linked list. */
53 void add_aes_entry(AES_ENTRY
**list
, uint16_t caid
, uint32_t ident
, int32_t keyid
, uint8_t *aesKey
)
55 AES_ENTRY
*new_entry
, *next
, *current
;
57 // create the AES key entry for the linked list
58 if(!cs_malloc(&new_entry
, sizeof(AES_ENTRY
)))
61 memcpy(new_entry
->plainkey
, aesKey
, 16);
62 new_entry
->caid
= caid
;
63 new_entry
->ident
= ident
;
64 new_entry
->keyid
= keyid
;
65 if(memcmp(aesKey
, "\xFF\xFF", 2))
67 AES_set_decrypt_key((const uint8_t *)aesKey
, 128, &(new_entry
->key
));
68 // cs_log("adding key : %s",cs_hexdump(1,aesKey,16, tmp, sizeof(tmp)));
72 memset(&new_entry
->key
, 0, sizeof(AES_KEY
));
73 // cs_log("adding fake key");
75 new_entry
->next
= NULL
;
77 //if list is empty, new_entry is the new head
84 //append it to the list
92 current
->next
= new_entry
;
95 /* Parses a single AES_KEYS entry and assigns it to the given list.
96 The expected format for value is caid1@ident1:key0,key1 */
97 void parse_aes_entry(AES_ENTRY
**list
, char *label
, char *value
)
103 int32_t nb_keys
, key_id
;
107 tmp
= strtok_r(value
, "@", &save
);
109 //if we got error caid
110 len
= cs_strlen(tmp
);
111 if(len
== 0 || len
> 4) { return; }
113 //if there is not value after @
114 len
= cs_strlen(save
);
115 if(len
== 0) { return; }
118 tmp
= strtok_r(NULL
, ":", &save
);
120 //if we got error ident
121 len
= cs_strlen(tmp
);
122 if(len
== 0 || len
> 6) { return; }
126 // now we need to split the key and add the entry to the reader.
129 while((tmp
= strtok_r(NULL
, ",", &save
)))
132 len
= cs_strlen(tmp
);
136 // FF means the card will do the AES decrypt
137 // 00 means we don't have the aes.
138 if((dummy
!= 0xFF && dummy
!= 0x00) || len
> 2)
141 cs_log("AES key length error .. not adding");
152 { memset(aes_key
, 0xFF, 16); }
154 { key_atob_l(tmp
, aes_key
, 32); }
155 // now add the key to the reader... TBD
156 add_aes_entry(list
, caid
, ident
, key_id
, aes_key
);
160 cs_log("%d AES key(s) added on reader %s for %04x@%06x", nb_keys
, label
, caid
, ident
);
163 /* Clears all entries from an AES list*/
164 void aes_clear_entries(AES_ENTRY
**list
)
166 AES_ENTRY
*current
, *next
;
172 next
= current
->next
;
173 add_garbage(current
);
178 /* Parses multiple AES_KEYS entrys in a reader section and assigns them to the reader.
179 The expected format for value is caid1@ident1:key0,key1;caid2@ident2:key0,key1 */
180 void parse_aes_keys(struct s_reader
*rdr
, char *value
)
184 AES_ENTRY
*newlist
= NULL
, *savelist
= rdr
->aes_list
;
186 for(entry
= strtok_r(value
, ";", &save
); entry
; entry
= strtok_r(NULL
, ";", &save
))
188 parse_aes_entry(&newlist
, rdr
->label
, entry
);
190 rdr
->aes_list
= newlist
;
191 aes_clear_entries(&savelist
);
194 static AES_ENTRY
*aes_list_find(AES_ENTRY
*list
, uint16_t caid
, uint32_t provid
, int32_t keyid
)
196 AES_ENTRY
*current
= list
;
199 if(current
->caid
== caid
&& current
->ident
== provid
&& current
->keyid
== keyid
)
201 current
= current
->next
;
205 cs_log("AES Decrypt key %d not found for %04X@%06X (aka V %06X E%X ...) ", keyid
, caid
, provid
, provid
, keyid
);
212 int32_t aes_decrypt_from_list(AES_ENTRY
*list
, uint16_t caid
, uint32_t provid
, int32_t keyid
, uint8_t *buf
, int32_t n
)
214 AES_ENTRY
*current
= aes_list_find(list
, caid
, provid
, keyid
);
219 // hack for card that do the AES decrypt themsleves
220 memset(&dummy
, 0, sizeof(AES_KEY
));
221 if(!memcmp(¤t
->key
, &dummy
, sizeof(AES_KEY
)))
226 for(i
= 0; i
< n
; i
+= 16)
227 { AES_decrypt(buf
+ i
, buf
+ i
, &(current
->key
)); }
228 return 1; // all ok, key decoded.
231 int32_t aes_present(AES_ENTRY
*list
, uint16_t caid
, uint32_t provid
, int32_t keyid
)
233 return aes_list_find(list
, caid
, provid
, keyid
) != NULL
;