comparison g23m/condat/com/src/comlib/sec_drv.c @ 0:509db1a7b7b8

initial import: leo2moko-r1
author Space Falcon <falcon@ivan.Harhan.ORG>
date Mon, 01 Jun 2015 03:24:05 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:509db1a7b7b8
1 #include "general.h"
2 #include "typedefs.h"
3 #include "vsi.h"
4 #include <stdlib.h>
5 #include <string.h>
6 #include "sec_drv.h"
7 #include "sec_drv_prim.h"
8
9 #ifdef FIRSTBOOT_ENABLED
10 #include "sec_firstboot.h"
11 #endif
12
13
14 #define UNLOCKED(status) ((status==SEC_DRV_CAT_STAT_Unlocked)||(status==SEC_DRV_CAT_STAT_PermUnlocked))
15
16
17 /**
18 * Resets the phone.
19 */
20 static void reset(void)
21 {
22 UINT16 i;
23
24 TRACE("** RESET **");
25 // Setup watchdog timer and let it timeout to make a reset
26 *(volatile UINT16*) 0xfffff804 = 0xFFFF; // Timer to watchdog
27 *(volatile UINT16*) 0xfffff800 = 0x0080; // Start timer
28 // Apparently works it only if we read this register?
29 i = *(volatile UINT16*) 0xfffff802;
30 *(volatile UINT16*) 0xfffff802 = 0x0001; // Load timer
31 }
32
33
34 /**
35 * Check whether or not we have valid lock data in the flash-area
36 * Run first_boot if we've got data, but its not initialized.
37 *
38 * @param pNumCategories Pointer to UINT8 where the number of
39 * categories will be stored.
40 * @return SEC_DRV_RET_Ok if theres valid data in the secure area.
41 */
42 static T_SEC_DRV_RETURN check_hdr(UINT8 *pNumCategories)
43 {
44 T_SEC_DRV_RETURN result = SEC_DRV_RET_Ok;
45 T_SEC_DRV_GLOBAL_CONF hdr;
46
47 TRACE("check_hdr");
48 if (sec_prim_get_global_conf(&hdr))
49 {
50 switch (hdr.firstboot_pattern)
51 {
52 case SEC_PATTERN_INITIALIZED:
53 /* Secure area seems to be initialized OK */
54 result = SEC_DRV_RET_Ok;
55 if (pNumCategories)
56 {
57 T_SEC_DRV_CONFIGURATION conf;
58 sec_prim_get_configuration(&conf);
59 *pNumCategories = conf.NumCategories;
60 }
61 TRACE("check_hdr - OK");
62 break;
63 case SEC_PATTERN_UNINITIALIZED:
64 /* We've got new data in the secure area that needs to be processed */
65 #ifdef FIRSTBOOT_ENABLED
66 first_boot();
67 #endif
68 result = SEC_DRV_RET_NotPresent;
69 TRACE("check_hdr - uninitialized");
70 reset();
71 break;
72 default:
73 /* Secure area seems to contain void data! */
74 result = SEC_DRV_RET_NotPresent;
75 if (pNumCategories) *pNumCategories = 0;
76 TRACE("check_hdr - void data");
77 break;
78 }
79 }
80 else
81 {
82 result = SEC_DRV_RET_NotPresent;
83 TRACE("check_hdr - void!!!");
84 }
85 return result;
86 }
87
88
89 /**
90 * Check if a counter is exceeded.
91 *
92 * @param pCount Pointer to current value - max value must follow immediately before!
93 * @return TRUE if the failure counter has been exceeded
94 */
95 static BOOL Counter_Exceeded(UINT8 *pCount)
96 {
97 pCount--;
98 return ((pCount[0] != 0xFF) && (pCount[1] >= pCount[0]));
99 }
100
101
102 /**
103 * Increment a counter if needed.
104 *
105 * @param pCount Pointer to the counter
106 */
107 static void Counter_Increment(UINT8 *pCount)
108 {
109 if ((*pCount) < 0xFF)
110 {
111 (*pCount)++;
112 }
113 }
114
115
116 /**
117 * Check whether or not a given key-len is ok according to its category.
118 *
119 * @param rec_num The record number to check the key_length against.
120 * @param key_len The key length to check.
121 * @return TRUE if the key_len is within specifications for the given
122 * record (category) - otherwise FALSE.
123 */
124 static BOOL check_key_len(int rec_num, UINT8 key_len)
125 {
126 if (key_len > SEC_DRV_KEY_MAX_LEN) return FALSE;
127 if ((rec_num == SEC_DRV_CAT_NUM_SIM) && (key_len < 6)) return FALSE;
128 if ((rec_num != SEC_DRV_CAT_NUM_SIM) && (key_len < 8)) return FALSE;
129 return TRUE;
130 }
131
132
133 /**
134 * Transform an unlock key into a special lock key - for use by the
135 * non-ETSI lock algorithm.
136 *
137 * @param pKey Pointer to a key to transform. This also serves as the output
138 * buffer. Must be '\0' terminated if shorter than SEC_DRV_KEY_MAX_LEN
139 */
140 void calculate_spec_lock_key(char *pKey)
141 {
142 int len=0;
143 int index;
144
145 while((len<SEC_DRV_KEY_MAX_LEN) && (pKey[len])) len++;
146 len = len & 0xFE;
147 for(index=0; index<len; index+=2)
148 {
149 char ch;
150 ch = pKey[index];
151 pKey[index] = pKey[index+1];
152 pKey[index+1] = ch;
153 }
154 }
155
156
157 /**
158 * Compare 2 keys up to key_len characters, given the length constraints implied
159 * by the category number and check_key_len().
160 *
161 * @param rec_num The category number to use when validating key_len.
162 * @param pRefKey Pointer to the key to use as reference (origin).
163 * @param pKey Pointer to the key to compare against pRefKey.
164 * @param key_len The maximum number of chars to use in the compare or 0 (to use all).
165 * @return SEC_DRV_RET_KeyWrong if the length constraints are violated, SEC_DRV_RET_Ok
166 * if the keys match, otherwise SEC_DRV_RET_KeyMismatch.
167 */
168 static T_SEC_DRV_RETURN compare_keys(int rec_num, const char *pRefKey, const char *pKey, UINT8 key_len)
169 {
170 if (pRefKey[0] == '\0')
171 {
172 TRACE("compare_keys - old key not present");
173 return SEC_DRV_RET_Ok;
174 }
175
176 if (key_len == 0)
177 {
178 /* compare using full length of the keys ->
179 to '\0' termination or max SEC_DRV_KEY_MAX_LEN chars...
180 whichever comes first */
181 key_len = SEC_DRV_KEY_MAX_LEN;
182 }
183 /* compare using the specified number of chars */
184 if (!check_key_len(rec_num, key_len) || (pKey==0L) || (pKey[0]=='\0')) return SEC_DRV_RET_KeyWrong;
185 return (strncmp(pRefKey, pKey, key_len)==0)? SEC_DRV_RET_Ok : SEC_DRV_RET_KeyMismatch;
186 }
187
188
189 /**
190 * Try to set a new key on a specific category. For this to happen, the new key must
191 * meet the length constraints implied by the category, and the current category key
192 * must match the given oldkey within the key_len chars (again, remember length
193 * constraints).
194 *
195 * @param rec_num The category number for which to set the key.
196 * @param pOldKey Key to compare against current category key. The 2 must match
197 * for the new key to be set.
198 * @param pNewKey Key to set the category to, if possible.
199 * @param key_len Length to use when comparing keys, see check_key_len().
200 * @return SEC_DRV_RET_Ok if the key could be set.
201 */
202 static T_SEC_DRV_RETURN set_key(T_SEC_DRV_CONFIGURATION *pConf, int rec_num, const char *pOldKey, const char *pNewKey, UINT8 key_len)
203 {
204 T_SEC_DRV_RETURN result;
205 T_SEC_DRV_KEY key;
206 if (sec_prim_get_key(rec_num, &key))
207 {
208 result = compare_keys(rec_num, (char *)key.digit, pOldKey, key_len);
209 if (result == SEC_DRV_RET_Ok)
210 {
211 int len = strlen(pNewKey);
212 if (check_key_len(rec_num, len))
213 {
214 len++; /* convert len into a size! */
215 if (len > SEC_DRV_KEY_MAX_LEN) len = SEC_DRV_KEY_MAX_LEN;
216 memcpy(key.digit, pNewKey, len);
217 sec_prim_set_key(rec_num, &key);
218 }
219 else
220 {
221 /* key must be within specified length according to category */
222 result = SEC_DRV_RET_KeyWrong;
223 }
224 }
225 else
226 {
227 Counter_Increment(&pConf->FC_Current);
228 sec_prim_set_configuration(pConf);
229 }
230 }
231 else
232 {
233 result = SEC_DRV_RET_NotPresent;
234 }
235 return result;
236 }
237
238
239 /**
240 * Update all dependant categories. Scanning through a categories dependants,
241 * set their status and key if needed.
242 *
243 * @param pCatHdr Pointer to the category header for the parent category.
244 * @param pCatKey Pointer to the key for the parent category.
245 */
246 static void update_dependants(const T_SEC_DRV_CAT_HDR *pCatHdr, const T_SEC_DRV_KEY *pCatKey, UINT16 dependMask)
247 {
248 int dependentCat = 0;
249 int dependentBit = 1;
250
251 for (; dependentCat<(sizeof(pCatHdr->Dependency)*8); dependentCat++)
252 {
253 if (pCatHdr->Dependency & dependentBit & dependMask)
254 {
255 {
256 /* set key on dependant iff not already done, and parent has a key */
257 T_SEC_DRV_KEY dependentKey;
258 if (sec_prim_get_key(dependentCat, &dependentKey))
259 {
260 if (pCatKey->digit[0] != '\0' && dependentKey.digit[0] == '\0')
261 {
262 sec_prim_set_key(dependentCat, pCatKey);
263 }
264 }
265 }
266 {
267 /* update status on dependant */
268 T_SEC_DRV_CAT_HDR dependentHdr;
269 if (sec_prim_get_cat_header(dependentCat, &dependentHdr))
270 {
271 if (dependentHdr.Status != SEC_DRV_CAT_STAT_PermUnlocked)
272 {
273 dependentHdr.Status = pCatHdr->Status;
274 sec_prim_set_cat_header(dependentCat, &dependentHdr);
275 }
276 }
277 }
278 }
279 dependentBit = dependentBit<<1;
280 }
281 }
282
283
284 /**
285 * Get the MEPD configuration.
286 *
287 * @param ppConfiguration Pointer to pointer where the configuration is stored.
288 * @return SEC_DRV_RET_Ok if the configuration could be read.
289 */
290 T_SEC_DRV_RETURN sec_get_CFG(T_SEC_DRV_CONFIGURATION **ppConfiguration)
291 {
292 T_SEC_DRV_RETURN result = check_hdr(0L);
293 if (result == SEC_DRV_RET_Ok)
294 {
295 *ppConfiguration = (T_SEC_DRV_CONFIGURATION *)M_ALLOC(sizeof(T_SEC_DRV_CONFIGURATION));
296 sec_prim_get_configuration(*ppConfiguration);
297 }
298 else
299 {
300 *ppConfiguration = 0L;
301 }
302 return result;
303 }
304
305
306 /**
307 * Compare a key against the one stored for a given category.
308 *
309 * @param rec_num The category number for which to check the key.
310 * @param pKey The key to compare.
311 * @param key_len The length of the keys to use in the compare. Subject to constraints.
312 * @return SEC_DRV_RET_Ok if the keys match
313 */
314 T_SEC_DRV_RETURN sec_cmp_KEY (UINT8 rec_num, const char *pKey, UINT8 key_len)
315 {
316 T_SEC_DRV_KEY refKey;
317 T_SEC_DRV_CONFIGURATION conf;
318 UINT8 numCategories=0;
319 T_SEC_DRV_RETURN result = check_hdr(&numCategories);
320 if (result != SEC_DRV_RET_Ok)
321 {
322 /* data not present in secure area! */
323 return result;
324 }
325
326 sec_prim_get_configuration(&conf);
327 if (Counter_Exceeded(&conf.FC_Current))
328 {
329 result = SEC_DRV_RET_FCExeeded;
330 }
331 else if (conf.Flags & SEC_DRV_HDR_FLAG_LAM_Unlock)
332 {
333 result = SEC_DRV_RET_Unknown;
334 }
335 else if (sec_prim_get_key(rec_num, &refKey))
336 {
337 result = compare_keys(rec_num, (char *)refKey.digit, pKey, key_len);
338 }
339 else
340 {
341 /* requested data outside configured categories! */
342 result = SEC_DRV_RET_NotPresent;
343 }
344 return result;
345 }
346
347
348 /**
349 * Try to set a key for a given category. The category must be unlocked prior
350 * to this attempt.
351 *
352 * @param rec_num Category number whoose key should be set.
353 * @param pOldKey pointer to current key of the category (or rather what the
354 * client believes to be the current key).
355 * @param pNewKey Pointer to the key that should be set.
356 * @param key_len length to use during key-comparision.
357 * @return SEC_DRV_RET_Ok if the key could be set.
358 */
359 T_SEC_DRV_RETURN sec_set_KEY (UINT8 rec_num, const char *pOldKey, const char *pNewKey, UINT8 key_len)
360 {
361 T_SEC_DRV_CONFIGURATION conf;
362 UINT8 numCategories=0;
363 T_SEC_DRV_CAT_HDR catHdr;
364 T_SEC_DRV_RETURN result = check_hdr(&numCategories);
365 if (result != SEC_DRV_RET_Ok)
366 {
367 /* data not present in secure area! */
368 return result;
369 }
370
371 sec_prim_get_configuration(&conf);
372 if (Counter_Exceeded(&conf.FC_Current))
373 {
374 result = SEC_DRV_RET_FCExeeded;
375 }
376 else if (sec_prim_get_cat_header(rec_num, &catHdr))
377 {
378 if (UNLOCKED(catHdr.Status) && !(conf.Flags & SEC_DRV_HDR_FLAG_LAM_Unlock))
379 {
380 result = set_key(&conf, rec_num, pOldKey, pNewKey, key_len);
381 }
382 else
383 {
384 /* category must be unlocked prior to setting a key */
385 result = SEC_DRV_RET_Unknown;
386 }
387 }
388 else
389 {
390 /* requested data outside configured categories! */
391 result = SEC_DRV_RET_NotPresent;
392 }
393 return result;
394 }
395
396
397 /**
398 * Set the key for tha failure counter.
399 *
400 * @param pOldKey The current failure count key. Must match that stored in the
401 * secure area for the new key to be set.
402 * @param pNewKey The new key to set for the failure counter.
403 * @return SEC_DRV_RET_Ok if the key could be set.
404 */
405 T_SEC_DRV_RETURN sec_set_FC_KEY (const char *pOldKey, const char *pNewKey)
406 {
407 T_SEC_DRV_CONFIGURATION conf;
408 T_SEC_DRV_RETURN result = check_hdr(0L);
409 if (result != SEC_DRV_RET_Ok)
410 {
411 /* data not present in secure area! */
412 return result;
413 }
414
415 sec_prim_get_configuration(&conf);
416 if (Counter_Exceeded(&conf.FC_Current))
417 {
418 result = SEC_DRV_RET_FCExeeded;
419 }
420 else
421 {
422 result = set_key(&conf, -1, pOldKey, pNewKey, 0);
423 }
424 return result;
425 }
426
427
428 /**
429 * Get the record data (both header and body) for a given category.
430 *
431 * @param rec_num The category number to get the data for.
432 * @param ppCategory Pointer to where the result pointer should be stored.
433 * @return SEC_DRV_RET_Ok if the record data could be read.
434 */
435 T_SEC_DRV_RETURN sec_get_REC (UINT8 rec_num, T_SEC_DRV_CATEGORY **ppCategory)
436 {
437 UINT8 numCategories=0;
438 T_SEC_DRV_RETURN result = check_hdr(&numCategories);
439 if (result != SEC_DRV_RET_Ok)
440 {
441 /* data not present in secure area! */
442 *ppCategory = 0L;
443 return result;
444 }
445
446 if (rec_num < numCategories)
447 {
448 *ppCategory = (T_SEC_DRV_CATEGORY *)M_ALLOC(sizeof(T_SEC_DRV_CATEGORY));
449 sec_prim_get_cat_header(rec_num, &(*ppCategory)->Header);
450 if ((*ppCategory)->Header.DataLen)
451 {
452 (*ppCategory)->pBody = M_ALLOC((*ppCategory)->Header.DataLen);
453 sec_prim_get_cat_body(rec_num, (*ppCategory)->pBody, (*ppCategory)->Header.DataLen);
454 }
455 else
456 {
457 (*ppCategory)->pBody = 0L;
458 }
459 result = SEC_DRV_RET_Ok;
460 }
461 else
462 {
463 /* requested data outside configured categories! */
464 *ppCategory = 0L;
465 result = SEC_DRV_RET_NotPresent;
466 }
467 return result;
468 }
469
470
471 /**
472 * Set the body part of a category's data. The data can only be set if the
473 * category is unlocked.
474 *
475 * @param rec_num Category number whose body part should be set.
476 * @param pBody Pointer to the body data that should be stored.
477 * @return SEC_DRV_RET_Ok if the data could be stored.
478 */
479 T_SEC_DRV_RETURN sec_set_REC (UINT8 rec_num, const T_SEC_DRV_CATEGORY *pCategory)
480 {
481 T_SEC_DRV_CAT_HDR header;
482 UINT8 numCategories=0;
483 T_SEC_DRV_RETURN result = check_hdr(&numCategories);
484 if (result != SEC_DRV_RET_Ok)
485 {
486 /* data not present in secure area! */
487 return result;
488 }
489
490 if (sec_prim_get_cat_header(rec_num, &header))
491 {
492 if (header.Status == SEC_DRV_CAT_STAT_Unlocked ||
493 header.Status == SEC_DRV_CAT_STAT_PermUnlocked)
494 {
495 sec_prim_set_cat_body(rec_num, pCategory->pBody, pCategory->Header.DataLen);
496 result = SEC_DRV_RET_Ok;
497 }
498 else
499 {
500 /* Category must be unlocked in order to write record data */
501 result = SEC_DRV_RET_Unknown;
502 }
503 }
504 else
505 {
506 /* requested data outside configured categories! */
507 result = SEC_DRV_RET_NotPresent;
508 }
509 return result;
510 }
511
512
513 /**
514 * Try to unlock a category. Failure count must not have been exeeded, NAM unlock
515 * must not be set and the category must not be linklocked. Also the given key
516 * must match the stored key for the category before it is unlocked.
517 *
518 * @param rec_num Category number that should be unlocked.
519 * @param pKey Key that should match the stored category key.
520 * @param key_len The maximum number of chars to use in the compare or 0 (to use all).
521 * @return SEC_DRV_RET_Ok if the category could be unlocked.
522 */
523 T_SEC_DRV_RETURN sec_rec_Unlock (UINT8 rec_num, T_SEC_DRV_UNLOCK_TYPE unlockType, const char *pKey, UINT8 key_len, UINT16 dependMask)
524 {
525 T_SEC_DRV_CONFIGURATION conf;
526 T_SEC_DRV_CAT_HDR catHdr;
527 UINT8 numCategories=0;
528 T_SEC_DRV_RETURN result = check_hdr(&numCategories);
529 if (result != SEC_DRV_RET_Ok)
530 {
531 /* data not present in secure area! */
532 return result;
533 }
534
535 sec_prim_get_configuration(&conf);
536 if (Counter_Exceeded(&conf.FC_Current))
537 {
538 result = SEC_DRV_RET_FCExeeded;
539 }
540 else if (sec_prim_get_cat_header(rec_num, &catHdr))
541 {
542 if (UNLOCKED(catHdr.Status) ||
543 (conf.Flags & SEC_DRV_HDR_FLAG_LAM_Unlock) ||
544 (catHdr.Flags & SEC_DRV_CAT_FLAG_LinkLocked))
545 {
546 /* NAM or LinkLock failure */
547 result = SEC_DRV_RET_Unknown;
548 }
549 else
550 {
551 T_SEC_DRV_KEY catKey;
552 sec_prim_get_key(rec_num, &catKey);
553 result = compare_keys(rec_num, (char *)catKey.digit, pKey, key_len);
554 if (result == SEC_DRV_RET_Ok)
555 {
556 /* update status */
557 catHdr.Status = (unlockType == TEMPORARY_UNLOCK)?
558 SEC_DRV_CAT_STAT_Unlocked :
559 SEC_DRV_CAT_STAT_PermUnlocked;
560 sec_prim_set_cat_header(rec_num, &catHdr);
561 /* update dependants */
562 update_dependants(&catHdr, &catKey, dependMask);
563 /* reset failure counter */
564 conf.FC_Current = 0;
565 sec_prim_set_configuration(&conf);
566 }
567 else
568 {
569 /* Failure comparing keys! -
570 update failure counter */
571 Counter_Increment(&conf.FC_Current);
572 sec_prim_set_configuration(&conf);
573 }
574 }
575 }
576 else
577 {
578 /* requested data outside configured categories! */
579 result = SEC_DRV_RET_NotPresent;
580 }
581 return result;
582 }
583
584
585 static T_SEC_DRV_RETURN lock_record(
586 UINT8 rec_num,
587 T_SEC_DRV_CAT_HDR *catHdr,
588 UINT16 dependMask)
589 {
590 T_SEC_DRV_KEY catKey;
591 catHdr->Status = SEC_DRV_CAT_STAT_Locked;
592 sec_prim_get_key(rec_num, &catKey);
593 sec_prim_set_cat_header(rec_num, catHdr);
594 update_dependants(catHdr, &catKey, dependMask);
595 return SEC_DRV_RET_Ok;
596 }
597
598
599 /**
600 * Try to lock a category. Actual algorith depends on flags set for the individual
601 * category.
602 *
603 * @param rec_num Category number that should be locked.
604 * @param pKey Key that should match (or be set in) the stored category key.
605 * @param key_len The maximum number of chars to use in the compare or 0 (to use all).
606 * @return SEC_DRV_RET_Ok if the category could be locked.
607 */
608 T_SEC_DRV_RETURN sec_rec_Lock (UINT8 rec_num, const char *pKey, UINT8 key_len, UINT16 dependMask)
609 {
610 T_SEC_DRV_CAT_HDR catHdr;
611 UINT8 numCategories=0;
612 T_SEC_DRV_RETURN result = check_hdr(&numCategories);
613 if (result != SEC_DRV_RET_Ok)
614 {
615 /* data not present in secure area! */
616 return result;
617 }
618
619 if (sec_prim_get_cat_header(rec_num, &catHdr))
620 {
621 if (catHdr.Status != SEC_DRV_CAT_STAT_Unlocked)
622 {
623 /* Status must be unlocked before locking! */
624 result = SEC_DRV_RET_Unknown;
625 }
626 else
627 {
628 if (rec_num == SEC_DRV_CAT_NUM_AP)
629 {
630 result = lock_record(rec_num, &catHdr, dependMask);
631 }
632 else
633 {
634 T_SEC_DRV_CONFIGURATION conf;
635 sec_prim_get_configuration(&conf);
636 if (conf.Flags & SEC_DRV_HDR_FLAG_ETSI_Flag)
637 {
638 /* ETSI Mode - set the category key */
639 int len = strlen(pKey);
640 if (check_key_len(rec_num, len))
641 {
642 T_SEC_DRV_KEY key;
643 memset(key.digit, 0, SEC_DRV_KEY_MAX_LEN);
644 memcpy(key.digit, pKey, len);
645 sec_prim_set_key(rec_num, &key);
646 result = lock_record(rec_num, &catHdr, dependMask);
647 }
648 else
649 {
650 /* Key has wrong length! */
651 result = SEC_DRV_RET_KeyWrong;
652 }
653 }
654 else if (conf.Flags & SEC_DRV_HDR_FLAG_LAM_Unlock)
655 {
656 /* Non-ETSI, but LAM_unlock is set */
657 result = SEC_DRV_RET_Unknown;
658 }
659 else
660 {
661 /* Non-ETSI mode */
662 T_SEC_DRV_KEY key;
663 sec_prim_get_key(rec_num, &key);
664 if (conf.Flags & SEC_DRV_HDR_FLAG_Spec_Lock_Key)
665 {
666 /* Special lock key enabled */
667 calculate_spec_lock_key((char *)&key.digit[0]);
668 }
669 result = compare_keys(rec_num, (char *)key.digit, pKey, key_len);
670 if (result == SEC_DRV_RET_Ok)
671 {
672 result = lock_record(rec_num, &catHdr, dependMask);
673 }
674 }
675 }
676 }
677 }
678 else
679 {
680 /* requested data outside configured categories! */
681 result = SEC_DRV_RET_NotPresent;
682 }
683 return result;
684 }
685
686
687 /**
688 * reset the failure counter. The correct key must of course be given.
689 *
690 * @param pKey The key used to try to reset the failure counter.
691 * @key_len Length of the key to use.
692 * @return SEC_DRV_RET_Ok if the failure counter could be reset.
693 */
694 T_SEC_DRV_RETURN sec_FC_Reset (const char *pKey, UINT8 key_len)
695 {
696 T_SEC_DRV_KEY refKey;
697 T_SEC_DRV_CONFIGURATION conf;
698 T_SEC_DRV_RETURN result = check_hdr(0L);
699 if (result != SEC_DRV_RET_Ok)
700 {
701 /* data not present in secure area! */
702 return result;
703 }
704
705 sec_prim_get_configuration(&conf);
706 if (Counter_Exceeded(&conf.FC_Reset_Fail_Current) ||
707 Counter_Exceeded(&conf.FC_Reset_Success_Current))
708 {
709 result = SEC_DRV_RET_FCExeeded;
710 }
711 else
712 {
713 sec_prim_get_key(-1, &refKey);
714 result = compare_keys(-1, (char *)refKey.digit, pKey, key_len);
715 if (result == SEC_DRV_RET_Ok)
716 {
717 Counter_Increment(&conf.FC_Reset_Success_Current);
718 conf.FC_Current = 0;
719 }
720 else
721 {
722 Counter_Increment(&conf.FC_Reset_Fail_Current);
723 }
724 sec_prim_set_configuration(&conf);
725 }
726 return result;
727 }
728
729
730 T_SEC_DRV_RETURN sec_FC_Increment(void)
731 {
732 T_SEC_DRV_RETURN result = SEC_DRV_RET_Ok;
733 T_SEC_DRV_CONFIGURATION conf;
734
735 sec_prim_get_configuration(&conf);
736 if (Counter_Exceeded(&conf.FC_Current))
737 {
738 result = SEC_DRV_RET_FCExeeded;
739 }
740 else
741 {
742 Counter_Increment(&conf.FC_Current);
743 sec_prim_set_configuration(&conf);
744 }
745 return result;
746 }
747