LED blink
[gnuk/gnuk.git] / src / flash.c
1 /*
2  * flash.c -- Data Objects (DO) and GPG Key handling on Flash ROM
3  *
4  * Copyright (C) 2010 Free Software Initiative of Japan
5  * Author: NIIBE Yutaka <gniibe@fsij.org>
6  *
7  * This file is a part of Gnuk, a GnuPG USB Token implementation.
8  *
9  * Gnuk is free software: you can redistribute it and/or modify it
10  * under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * Gnuk is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
17  * License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23
24 /*
25  * We assume single DO size is less than 256.
26  *
27  * NOTE: When we will support "Card holder certificate" (which size is
28  *       larger than 256), it will not be put into data pool, but will
29  *       be implemented by its own flash page.
30  */
31
32 #include "config.h"
33 #include "ch.h"
34 #include "hal.h"
35 #include "gnuk.h"
36
37 #define FLASH_KEY1               0x45670123UL
38 #define FLASH_KEY2               0xCDEF89ABUL
39
40 enum flash_status
41 {
42   FLASH_BUSY = 1,
43   FLASH_ERROR_PG,
44   FLASH_ERROR_WRP,
45   FLASH_COMPLETE,
46   FLASH_TIMEOUT
47 };
48
49 static void
50 flash_unlock (void)
51 {
52   FLASH->KEYR = FLASH_KEY1;
53   FLASH->KEYR = FLASH_KEY2;
54 }
55
56 static int
57 flash_get_status (void)
58 {
59   int status;
60
61   if ((FLASH->SR & FLASH_SR_BSY) != 0)
62     status = FLASH_BUSY;
63   else if ((FLASH->SR & FLASH_SR_PGERR) != 0)
64     status = FLASH_ERROR_PG;
65   else if((FLASH->SR & FLASH_SR_WRPRTERR) != 0 )
66     status = FLASH_ERROR_WRP;
67   else
68     status = FLASH_COMPLETE;
69
70   return status;
71 }
72
73 static int
74 flash_wait_for_last_operation (uint32_t timeout)
75 {
76   int status;
77
78   do
79     if (--timeout == 0)
80       return FLASH_TIMEOUT;
81     else
82       status = flash_get_status ();
83   while (status == FLASH_BUSY);
84
85   return status;
86 }
87
88 #define FLASH_PROGRAM_TIMEOUT 0x00010000
89 #define FLASH_ERASE_TIMEOUT   0x01000000
90
91 static int
92 flash_program_halfword (uint32_t addr, uint16_t data)
93 {
94   int status;
95
96   status = flash_wait_for_last_operation (FLASH_PROGRAM_TIMEOUT);
97
98   chSysLock ();
99   if (status == FLASH_COMPLETE)
100     {
101       FLASH->CR |= FLASH_CR_PG;
102
103       *(volatile uint16_t *)addr = data;
104
105       status = flash_wait_for_last_operation (FLASH_PROGRAM_TIMEOUT);
106       if (status != FLASH_TIMEOUT)
107         FLASH->CR &= ~FLASH_CR_PG;
108     }
109   chSysUnlock ();
110
111   return status;
112 }
113
114 static int
115 flash_erase_page (uint32_t addr)
116 {
117   int status;
118
119   status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT);
120
121   chSysLock ();
122   if (status == FLASH_COMPLETE)
123     {
124       FLASH->CR |= FLASH_CR_PER;
125       FLASH->AR = addr; 
126       FLASH->CR |= FLASH_CR_STRT;
127
128       status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT);
129       if (status != FLASH_TIMEOUT)
130         FLASH->CR &= ~FLASH_CR_PER;
131     }
132   chSysUnlock ()
133
134   return status;
135 }
136
137 /*
138  * Flash memory map
139  *
140  * _text
141  *         .text
142  *         .ctors
143  *         .dtors
144  * _etext
145  *         .data
146  *         ...
147  * _etext + (_edata - _data)
148  *
149  * flash-page-size align padding
150  *
151  * flash-page-size data pool  * 2
152  *
153  * 1.5-KiB Key store (512-byte (p, q and N) key-store * 3)
154  */
155 #define FLASH_DATA_POOL_HEADER_SIZE     2
156 #if defined(STM32F10X_HD)
157 #define FLASH_PAGE_SIZE                 2048
158 #else
159 #define FLASH_PAGE_SIZE                 1024
160 #endif
161 #define FLASH_DATA_POOL_SIZE            (FLASH_PAGE_SIZE*2)
162 #define FLASH_KEYSTORE_SIZE             (512*3)
163
164 static const uint8_t *data_pool;
165 static const uint8_t *keystore_pool;
166
167 static uint8_t *last_p;
168 static const uint8_t *keystore;
169
170 /* The first halfward is generation for the data page (little endian) */
171 const uint8_t const flash_data[4] __attribute__ ((section (".gnuk_data"))) = {
172   0x01, 0x00, 0xff, 0xff
173 };
174
175 /* Linker set this symbol */
176 extern uint8_t _data_pool;
177
178 const uint8_t *
179 flash_init (void)
180 {
181   const uint8_t *p;
182   extern uint8_t _keystore_pool;
183   uint16_t gen0, gen1;
184   uint16_t *gen0_p = (uint16_t *)&_data_pool;
185   uint16_t *gen1_p = (uint16_t *)(&_data_pool + FLASH_PAGE_SIZE);
186
187   /* Check data pool generation and choose the page */
188   gen0 = *gen0_p;
189   gen1 = *gen1_p;
190   if (gen0 == 0xffff)
191     data_pool = &_data_pool + FLASH_PAGE_SIZE;
192   else if (gen1 == 0xffff)
193     data_pool = &_data_pool;
194   else if (gen1 > gen0)
195     data_pool = &_data_pool + FLASH_PAGE_SIZE;
196   else
197     data_pool = &_data_pool;
198
199   keystore_pool = &_keystore_pool;
200
201   /* Seek empty keystore */
202   p = keystore_pool;
203   while (*p != 0xff || *(p+1) != 0xff)
204     p += 512;
205
206   keystore = p;
207
208   flash_unlock ();
209   return data_pool + FLASH_DATA_POOL_HEADER_SIZE;
210 }
211
212 /*
213  * Flash data pool managenent
214  *
215  * Flash data pool consists of two parts:
216  *   2-byte header
217  *   contents
218  *
219  * Flash data pool objects:
220  *   Data Object (DO) (of smart card)
221  *   Internal objects:
222  *     NONE (0x0000)
223  *     123-counter
224  *     14-bit counter
225  *     bool object
226  *
227  * Format of a Data Object:
228  *    NR:   8-bit tag_number
229  *    LEN:  8-bit length
230  *    DATA: data * LEN
231  *    PAD:  optional byte for 16-bit alignment
232  */
233
234 void
235 flash_set_data_pool_last (const uint8_t *p)
236 {
237   last_p = (uint8_t *)p;
238 }
239
240 /*
241  * We use two pages
242  */
243 static int
244 flash_copying_gc (void)
245 {
246   uint8_t *src, *dst;
247   uint16_t generation;
248
249   if (data_pool == &_data_pool)
250     {
251       src = &_data_pool;
252       dst = &_data_pool + FLASH_PAGE_SIZE;
253     }
254   else
255     {
256       src = &_data_pool + FLASH_PAGE_SIZE;
257       dst = &_data_pool;
258     }
259
260   generation = *(uint16_t *)src;
261   data_pool = dst;
262   gpg_data_copy (data_pool + FLASH_DATA_POOL_HEADER_SIZE);
263   flash_erase_page ((uint32_t)src);
264   flash_program_halfword ((uint32_t)dst, generation+1);
265   return 0;
266 }
267
268 static int
269 is_data_pool_full (size_t size)
270 {
271   return last_p + size > data_pool + FLASH_PAGE_SIZE;
272 }
273
274 static uint8_t *
275 flash_data_pool_allocate (size_t size)
276 {
277   uint8_t *p;
278
279   size = (size + 1) & ~1;       /* allocation unit is 1-halfword (2-byte) */
280
281   if (is_data_pool_full (size))
282     if (flash_copying_gc () < 0 || /*still*/ is_data_pool_full (size))
283       fatal (FATAL_FLASH);
284
285   p = last_p;
286   last_p += size;
287   return p;
288 }
289
290 void
291 flash_do_write_internal (const uint8_t *p, int nr, const uint8_t *data, int len)
292 {
293   uint16_t hw;
294   uint32_t addr;
295   int i;
296
297   addr = (uint32_t)p;
298   hw = nr | (len << 8);
299   if (flash_program_halfword (addr, hw) != FLASH_COMPLETE)
300     flash_warning ("DO WRITE ERROR");
301   addr += 2;
302
303   for (i = 0; i < len/2; i ++)
304     {
305       hw = data[i*2] | (data[i*2+1]<<8);
306       if (flash_program_halfword (addr, hw) != FLASH_COMPLETE)
307         flash_warning ("DO WRITE ERROR");
308       addr += 2;
309     }
310
311   if ((len & 1))
312     {
313       hw = data[i*2] | 0xff00;
314       if (flash_program_halfword (addr, hw) != FLASH_COMPLETE)
315         flash_warning ("DO WRITE ERROR");
316       addr += 2;
317     }
318 }
319
320 const uint8_t *
321 flash_do_write (uint8_t nr, const uint8_t *data, int len)
322 {
323   const uint8_t *p;
324
325   DEBUG_INFO ("flash DO\r\n");
326
327   p = flash_data_pool_allocate (2 + len);
328   if (p == NULL)
329     {
330       DEBUG_INFO ("flash data pool allocation failure.\r\n");
331       return NULL;
332     }
333
334   flash_do_write_internal (p, nr, data, len);
335   DEBUG_INFO ("flash DO...done\r\n");
336   return p + 1;
337 }
338
339 void
340 flash_warning (const char *msg)
341 {
342   (void)msg;
343   DEBUG_INFO ("FLASH: ");
344   DEBUG_INFO (msg);
345   DEBUG_INFO ("\r\n");
346 }
347
348 void
349 flash_do_release (const uint8_t *do_data)
350 {
351   uint32_t addr = (uint32_t)do_data - 1;
352   uint32_t addr_tag = addr;
353   int i;
354   int len = do_data[0];
355
356   /* Don't filling zero for data in code (such as ds_count_initial_value) */
357   if (do_data < &_data_pool || do_data > &_data_pool + FLASH_DATA_POOL_SIZE)
358     return;
359
360   addr += 2;
361
362   /* Fill zero for content and pad */
363   for (i = 0; i < len/2; i ++)
364     {
365       if (flash_program_halfword (addr, 0) != FLASH_COMPLETE)
366         flash_warning ("fill-zero failure");
367       addr += 2;
368     }
369
370   if ((len & 1))
371     {
372       if (flash_program_halfword (addr, 0) != FLASH_COMPLETE)
373         flash_warning ("fill-zero pad failure");
374       addr += 2;
375     }
376
377   /* Fill 0x0000 for "tag_number and length" word */
378   if (flash_program_halfword (addr_tag, 0) != FLASH_COMPLETE)
379     flash_warning ("fill-zero tag_nr failure");
380 }
381
382 uint8_t *
383 flash_key_alloc (void)
384 {
385   uint8_t *k = (uint8_t *)keystore;
386
387   if ((k - keystore_pool) >= FLASH_KEYSTORE_SIZE)
388     return NULL;
389
390   keystore += 512;
391   return k;
392 }
393
394 int
395 flash_key_write (uint8_t *key_addr, const uint8_t *key_data,
396                  const uint8_t *modulus)
397 {
398   uint16_t hw;
399   uint32_t addr;
400   int i;
401
402   addr = (uint32_t)key_addr;
403   for (i = 0; i < KEY_CONTENT_LEN/2; i ++)
404     {
405       hw = key_data[i*2] | (key_data[i*2+1]<<8);
406       if (flash_program_halfword (addr, hw) != FLASH_COMPLETE)
407         return -1;
408       addr += 2;
409     }
410
411   for (i = 0; i < KEY_CONTENT_LEN/2; i ++)
412     {
413       hw = modulus[i*2] | (modulus[i*2+1]<<8);
414       if (flash_program_halfword (addr, hw) != FLASH_COMPLETE)
415         return -1;
416       addr += 2;
417     }
418
419   return 0;
420 }
421
422 void
423 flash_keystore_release (void)
424 {
425   flash_erase_page ((uint32_t)keystore_pool);
426 #if FLASH_KEYSTORE_SIZE > FLASH_PAGE_SIZE
427   flash_erase_page ((uint32_t)keystore_pool + FLASH_PAGE_SIZE);
428 #endif
429   keystore = keystore_pool;
430 }
431
432 void
433 flash_clear_halfword (uint32_t addr)
434 {
435   flash_program_halfword (addr, 0);
436 }
437
438
439 void
440 flash_put_data_internal (const uint8_t *p, uint16_t hw)
441 {
442   flash_program_halfword ((uint32_t)p, hw);
443 }
444
445 void
446 flash_put_data (uint16_t hw)
447 {
448   uint8_t *p;
449
450   p = flash_data_pool_allocate (2);
451   if (p == NULL)
452     {
453       DEBUG_INFO ("data allocation failure.\r\n");
454     }
455
456   flash_program_halfword ((uint32_t)p, hw);
457 }
458
459
460 void
461 flash_bool_clear (const uint8_t **addr_p)
462 {
463   const uint8_t *p;
464
465   if ((p = *addr_p) == NULL)
466     return;
467
468   flash_program_halfword ((uint32_t)p, 0);
469   *addr_p = NULL;
470 }
471
472 void
473 flash_bool_write_internal (const uint8_t *p, int nr)
474 {
475   flash_program_halfword ((uint32_t)p, nr);
476 }
477
478 const uint8_t *
479 flash_bool_write (uint8_t nr)
480 {
481   uint8_t *p;
482   uint16_t hw = nr;
483
484   p = flash_data_pool_allocate (2);
485   if (p == NULL)
486     {
487       DEBUG_INFO ("bool allocation failure.\r\n");
488       return NULL;
489     }
490
491   flash_program_halfword ((uint32_t)p, hw);
492   return p;
493 }
494
495
496 int
497 flash_cnt123_get_value (const uint8_t *p)
498 {
499   if (p == NULL)
500     return 0;
501   else
502     {
503       uint8_t v = *p;
504
505       /*
506        * After erase, a halfword in flash memory becomes 0xffff.
507        * The halfword can be programmed to any value.
508        * Then, the halfword can be programmed to zero.
509        *
510        * Thus, we can represent value 1, 2, and 3.
511        */
512       if (v == 0xff)
513         return 1;
514       else if (v == 0x00)
515         return 3;
516       else
517         return 2;
518     }
519 }
520
521 void
522 flash_cnt123_write_internal (const uint8_t *p, int which, int v)
523 {
524   uint16_t hw;
525
526   hw = NR_COUNTER_123 | (which << 8);
527   flash_program_halfword ((uint32_t)p, hw);
528
529   if (v == 1)
530     return;
531   else if (v == 2)
532     flash_program_halfword ((uint32_t)p+2, 0xc3c3);
533   else                          /* v == 3 */
534     flash_program_halfword ((uint32_t)p+2, 0);
535 }
536
537 void
538 flash_cnt123_increment (uint8_t which, const uint8_t **addr_p)
539 {
540   const uint8_t *p;
541   uint16_t hw;
542
543   if ((p = *addr_p) == NULL)
544     {
545       p = flash_data_pool_allocate (4);
546       if (p == NULL)
547         {
548           DEBUG_INFO ("cnt123 allocation failure.\r\n");
549           return;
550         }
551       hw = NR_COUNTER_123 | (which << 8);
552       flash_program_halfword ((uint32_t)p, hw);
553       *addr_p = p + 2;
554     }
555   else
556     {
557       uint8_t v = *p;
558
559       if (v == 0)
560         return;
561
562       if (v == 0xff)
563         hw = 0xc3c3;
564       else
565         hw = 0;
566
567       flash_program_halfword ((uint32_t)p, hw);
568     }
569 }
570
571 void
572 flash_cnt123_clear (const uint8_t **addr_p)
573 {
574   const uint8_t *p;
575
576   if ((p = *addr_p) == NULL)
577     return;
578
579   flash_program_halfword ((uint32_t)p, 0);
580   p -= 2;
581   flash_program_halfword ((uint32_t)p, 0);
582   *addr_p = NULL;
583 }