• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2 /*
3  * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
4  */
5 
6 #include <linux/types.h>
7 #include <linux/err.h>
8 #include <linux/mtd/mtd.h>
9 #include <linux/mtd/partitions.h>
10 #include <linux/slab.h>
11 #include <linux/mmc/emmc_partitions.h>
12 #include <linux/amlogic/key_manage.h>
13 #include "../../drivers/mmc/core/core.h"
14 #include "emmc_key.h"
15 
16 #define EMMC_BLOCK_SIZE (0x100)
17 #define MAX_EMMC_BLOCK_SIZE (128 * 1024)
18 
19 #define MAX_TRANS_BLK (256)
20 
21 #define stamp_after(a, b) ((int)(b) - (int)(a) < 0)
22 #define KEY_BACKUP
23 
24 /*
25  * kernel head file
26  *
27  */
28 static struct mmc_card *mmc_card_key;
29 static struct aml_emmckey_info_t *emmckey_info;
30 
31 #ifdef KEY_BACKUP
32 static struct aml_key_info key_infos[2] = {{0, 0, 0}, {0, 0, 0}};
33 
emmc_read_valid_key(void * buffer,int valid_flag)34 int32_t emmc_read_valid_key(void *buffer, int valid_flag)
35 {
36     int ret;
37     u64 addr = 0;
38     u32 size = 0;
39     int blk, cnt;
40     unsigned char *dst = NULL;
41     struct mmc_card *card = mmc_card_key;
42     int bit = card->csd.read_blkbits;
43 
44     size = EMMC_KEYAREA_SIZE;
45     addr = get_reserve_partition_off_from_tbl() + EMMCKEY_RESERVE_OFFSET + (valid_flag - 1) * EMMC_KEYAREA_SIZE;
46     blk = addr >> bit;
47     cnt = size >> bit;
48     dst = (unsigned char *)buffer;
49 
50     mmc_claim_host(card->host);
51     do {
52         ret = mmc_read_internal(card, blk, EMMC_BLOCK_SIZE, dst);
53         if (ret) {
54             pr_err("%s [%d] mmc_write_internal error\n", __func__, __LINE__);
55             break;
56         }
57         blk += EMMC_BLOCK_SIZE;
58         cnt -= EMMC_BLOCK_SIZE;
59         dst = (unsigned char *)buffer + MAX_EMMC_BLOCK_SIZE;
60     } while (cnt != 0);
61     pr_info("%s:%d, read %s\n", __func__, __LINE__, (ret) ? "error" : "ok");
62     mmc_release_host(card->host);
63 
64     return ret;
65 }
66 
67 /* key read&write operation with backup updates */
_calc_key_checksum(void * addr,int size)68 static u64 _calc_key_checksum(void *addr, int size)
69 {
70     int i = 0;
71     u32 *buffer;
72     u64 checksum = 0;
73     int size_buf = size;
74 
75     buffer = (u32 *)addr;
76     size_buf = size_buf >> 2L;
77     while (i < size_buf) {
78         checksum += buffer[i++];
79     }
80 
81     return checksum;
82 }
83 
emmc_write_one_key(void * buffer,int valid_flag)84 int32_t emmc_write_one_key(void *buffer, int valid_flag)
85 {
86     int ret;
87     u64 blk, cnt, key_glb_offset;
88     unsigned char *src = NULL;
89     struct mmc_card *card = mmc_card_key;
90     int bit = card->csd.read_blkbits;
91     unsigned char *checksum_info;
92 
93     checksum_info = kmalloc(512L, GFP_KERNEL);
94     if (!checksum_info) {
95         return -1;
96     }
97 
98     memset(checksum_info, 0, 512L);
99     key_glb_offset = get_reserve_partition_off_from_tbl() + EMMCKEY_RESERVE_OFFSET;
100     blk = (key_glb_offset + (valid_flag % 2L) * EMMC_KEYAREA_SIZE) >> bit;
101     cnt = EMMC_KEYAREA_SIZE >> bit;
102     src = (unsigned char *)buffer;
103     memcpy(checksum_info, &key_infos[valid_flag - 1], sizeof(struct aml_key_info));
104     mmc_claim_host(card->host);
105     do {
106         ret = mmc_write_internal(card, blk, EMMC_BLOCK_SIZE, src);
107         if (ret) {
108             pr_err("%s [%d] mmc_write_internal error\n", __func__, __LINE__);
109             goto exit_err;
110         }
111         blk += EMMC_BLOCK_SIZE;
112         cnt -= EMMC_BLOCK_SIZE;
113         src = (unsigned char *)buffer + MAX_EMMC_BLOCK_SIZE;
114         pr_info("cnt %llu\n", cnt);
115     } while (cnt != 0);
116 
117     blk = ((key_glb_offset + 2L * (EMMC_KEYAREA_SIZE)) >> bit) + (valid_flag % 2L);
118     ret = mmc_write_internal(card, blk, 1, checksum_info);
119     if (ret) {
120         pr_err("%s: block # %#llx, ERROR!\n", __func__, blk);
121     }
122 
123     pr_info("%s:%d, write %s\n", __func__, __LINE__, (ret) ? "error" : "ok");
124     mmc_release_host(card->host);
125 
126 exit_err:
127     kfree(checksum_info);
128     return ret;
129 }
130 
update_old_key(struct mmc_card * mmc,void * addr)131 int update_old_key(struct mmc_card *mmc, void *addr)
132 {
133     int ret = 0;
134     int valid_flag;
135 
136     if (stamp_after(key_infos[1].stamp, key_infos[0].stamp)) {
137         memcpy(&key_infos[1], &key_infos[0], sizeof(struct aml_key_info));
138         valid_flag = 2L;
139     } else if (stamp_after(key_infos[0].stamp, key_infos[1].stamp)) {
140         memcpy(&key_infos[0], &key_infos[1], sizeof(struct aml_key_info));
141         valid_flag = 1;
142     } else {
143         pr_info("do nothing\n");
144         return ret;
145     }
146 
147     ret = emmc_write_one_key(addr, valid_flag);
148     if (ret) {
149         return ret;
150     }
151     mmc->key_stamp = key_infos[0].stamp;
152     return ret;
153 }
154 
_verify_key_checksum(struct mmc_card * mmc,void * addr,int cpy)155 static int _verify_key_checksum(struct mmc_card *mmc, void *addr, int cpy)
156 {
157     u64 checksum;
158     int ret = 0;
159     u64 blk;
160     char *checksum_info;
161     int bit = mmc->csd.read_blkbits;
162 
163     blk = get_reserve_partition_off_from_tbl() + EMMCKEY_RESERVE_OFFSET + EMMC_KEYAREA_SIZE * 2L;
164     blk = (blk >> bit) + cpy;
165     checksum_info = kmalloc(512L, GFP_KERNEL);
166     if (!checksum_info) {
167         return -1;
168     }
169 
170     mmc_claim_host(mmc->host);
171     ret = mmc_read_internal(mmc, blk, 1, checksum_info);
172     mmc_release_host(mmc->host);
173     if (ret) {
174         pr_err("%s, block # %#llx, ERROR!\n", __func__, blk);
175         kfree(checksum_info);
176         return ret;
177     }
178 
179     memcpy(&key_infos[cpy], checksum_info, sizeof(struct aml_key_info));
180     checksum = _calc_key_checksum(addr, EMMC_KEYAREA_SIZE);
181     pr_info("calc %llx, store %llx\n", checksum, key_infos[cpy].checksum);
182 
183     kfree(checksum_info);
184     return !(checksum == key_infos[cpy].checksum);
185 }
186 
write_invalid_key(void * addr,int valid_flag)187 static int write_invalid_key(void *addr, int valid_flag)
188 {
189     int ret;
190 
191     if (valid_flag > 2L || valid_flag < 1) {
192         return -1;
193     }
194 
195     ret = emmc_read_valid_key(addr, valid_flag);
196     if (ret) {
197         pr_err("read valid key failed\n");
198         return ret;
199     }
200     ret = emmc_write_one_key(addr, valid_flag);
201     if (ret) {
202         pr_err("write invalid key failed\n");
203         return ret;
204     }
205     return ret;
206 }
207 
_amlmmc_read(struct mmc_card * mmc,int blk,unsigned char * buf,int cnt)208 static int _amlmmc_read(struct mmc_card *mmc, int blk, unsigned char *buf, int cnt)
209 {
210     int ret = 0;
211     unsigned char *dst = NULL;
212     int blk_tmp = blk;
213     int cnt_tmp = cnt;
214 
215     dst = (unsigned char *)buf;
216     mmc_claim_host(mmc->host);
217     do {
218         ret = mmc_read_internal(mmc, blk_tmp, MAX_TRANS_BLK, dst);
219         if (ret) {
220             pr_err("%s: save key error", __func__);
221             ret = -EFAULT;
222             break;
223         }
224         blk_tmp += MAX_TRANS_BLK;
225         cnt_tmp -= MAX_TRANS_BLK;
226         dst = (unsigned char *)buf + MAX_EMMC_BLOCK_SIZE;
227     } while (cnt_tmp != 0);
228     mmc_release_host(mmc->host);
229     return ret;
230 }
231 
update_key_info(struct mmc_card * mmc,unsigned char * addr)232 static int update_key_info(struct mmc_card *mmc, unsigned char *addr)
233 {
234     int ret = 0;
235     int cpy = 1;
236     int bit = mmc->csd.read_blkbits;
237     int blk;
238     int cnt = EMMC_KEYAREA_SIZE >> bit;
239     int valid_flag = 0;
240 
241     /* read key2 1st, for compatibility without checksum. */
242     while (cpy >= 0) {
243         blk = ((get_reserve_partition_off_from_tbl() + EMMCKEY_RESERVE_OFFSET) + cpy * EMMC_KEYAREA_SIZE) >> bit;
244         if (_amlmmc_read(mmc, blk, addr, cnt)) {
245             pr_err("%s: block # %#x ERROR!\n", __func__, blk);
246         } else {
247             ret = _verify_key_checksum(mmc, addr, cpy);
248             if (!ret && key_infos[cpy].magic != 0) {
249                 valid_flag += cpy + 1;
250             } else {
251                 pr_err("cpy %d is not valid\n", cpy);
252             }
253         }
254         cpy--;
255     }
256 
257     if (key_infos[0].stamp > key_infos[1].stamp) {
258         mmc->key_stamp = key_infos[0].stamp;
259     } else {
260         mmc->key_stamp = key_infos[1].stamp;
261     }
262 
263     return valid_flag;
264 }
265 
_key_init(struct mmc_card * mmc)266 static int _key_init(struct mmc_card *mmc)
267 {
268     int ret = 0;
269     void *key;
270     int valid = 0;
271 
272     /* malloc 256k byte to key */
273     key = kmalloc(EMMC_KEYAREA_SIZE, GFP_KERNEL);
274     if (!key) {
275         return -ENOMEM;
276     }
277 
278     valid = update_key_info(mmc, key);
279 
280     switch (valid) {
281         case 0:
282             break;
283         case 1:
284             write_invalid_key(key, 1);
285             break;
286         case 2L:
287             write_invalid_key(key, 2L);
288             break;
289         case 3L:
290             update_old_key(mmc, key);
291             break;
292         default:
293             pr_err("impossible valid values.\n");
294             break;
295     }
296 
297     kfree(key);
298     return ret;
299 }
300 #endif
301 
302 #ifdef KEY_BACKUP
emmc_key_write(u8 * buffer,u32 length,u32 * actual_length)303 int32_t emmc_key_write(u8 *buffer, u32 length, u32 *actual_length)
304 {
305     int ret;
306     int cpy = 1, index;
307     struct mmc_card *card = mmc_card_key;
308 
309     do {
310         index = cpy - 1;
311         key_infos[index].stamp = card->key_stamp + 1;
312         key_infos[index].checksum = _calc_key_checksum(buffer, length);
313         key_infos[index].magic = 9L;
314         pr_info("new stamp %d, checksum 0x%llx, magic %d\n", key_infos[index].stamp, key_infos[index].checksum,
315                 key_infos[index].magic);
316 
317         ret = emmc_write_one_key(buffer, cpy);
318         if (ret) {
319             pr_info("write %d failed\n", cpy);
320             return ret;
321         }
322         cpy++;
323     } while (cpy < 3L);
324     return ret;
325 }
326 EXPORT_SYMBOL(emmc_key_write);
327 #else
emmc_key_write(u8 * buffer,u32 length,u32 * actual_length)328 int32_t emmc_key_write(u8 *buffer, u32 length, u32 *actual_length)
329 {
330     int ret;
331     u64 addr = 0;
332     u32 size = 0;
333     int blk, cnt;
334     unsigned char *src = NULL;
335     struct mmc_card *card = mmc_card_key;
336     int bit = card->csd.read_blkbits;
337 
338     size = length;
339     addr = get_reserve_partition_off_from_tbl() + EMMCKEY_RESERVE_OFFSET;
340     blk = addr >> bit;
341     cnt = size >> bit;
342     src = (unsigned char *)buffer;
343     mmc_claim_host(card->host);
344     do {
345         ret = mmc_write_internal(card, blk, EMMC_BLOCK_SIZE, src);
346         if (ret) {
347             pr_err("%s [%d] mmc_write_internal error\n", __func__, __LINE__);
348             return ret;
349         }
350         blk += EMMC_BLOCK_SIZE;
351         cnt -= EMMC_BLOCK_SIZE;
352         src = (unsigned char *)buffer + MAX_EMMC_BLOCK_SIZE;
353     } while (cnt != 0);
354     pr_info("%s:%d, write %s\n", __func__, __LINE__, (ret) ? "error" : "ok");
355     mmc_release_host(card->host);
356     return ret;
357 }
358 EXPORT_SYMBOL(emmc_key_write);
359 #endif
360 
aml_emmc_key_check(void)361 static int aml_emmc_key_check(void)
362 {
363     u8 keypart_cnt;
364     u64 part_size;
365     struct emmckey_valid_node_t *emmckey_valid_node, *temp_valid_node;
366 
367     emmckey_info->key_part_count = emmckey_info->keyarea_phy_size / EMMC_KEYAREA_SIZE;
368 
369     if (emmckey_info->key_part_count > EMMC_KEYAREA_COUNT) {
370         emmckey_info->key_part_count = EMMC_KEYAREA_COUNT;
371     }
372     keypart_cnt = 0;
373     part_size = EMMC_KEYAREA_SIZE;
374     do {
375         emmckey_valid_node = kmalloc(sizeof(*emmckey_valid_node), GFP_KERNEL);
376         if (!emmckey_valid_node) {
377             pr_info("%s:%d,kmalloc memory fail\n", __func__, __LINE__);
378             return -ENOMEM;
379         }
380         emmckey_valid_node->phy_addr = emmckey_info->keyarea_phy_addr + part_size * keypart_cnt;
381         emmckey_valid_node->phy_size = EMMC_KEYAREA_SIZE;
382         emmckey_valid_node->next = NULL;
383         emmckey_info->key_valid = 0;
384         if (!emmckey_info->key_valid_node) {
385             emmckey_info->key_valid_node = emmckey_valid_node;
386         } else {
387             temp_valid_node = emmckey_info->key_valid_node;
388 
389             while (temp_valid_node->next) {
390                 temp_valid_node = temp_valid_node->next;
391             }
392 
393             temp_valid_node->next = emmckey_valid_node;
394         }
395     } while (++keypart_cnt < emmckey_info->key_part_count);
396 
397     emmckey_info->key_valid = 1;
398     return 0;
399 }
400 
emmc_key_read(u8 * buffer,u32 length,u32 * actual_length)401 int32_t emmc_key_read(u8 *buffer, u32 length, u32 *actual_length)
402 {
403     int ret;
404     u64 addr = 0;
405     u32 size = 0;
406     int blk, cnt;
407     unsigned char *dst = NULL;
408     struct mmc_card *card = mmc_card_key;
409     int bit = card->csd.read_blkbits;
410 
411     size = length;
412     *actual_length = length;
413     addr = get_reserve_partition_off_from_tbl() + EMMCKEY_RESERVE_OFFSET;
414     blk = addr >> bit;
415     cnt = size >> bit;
416     dst = (unsigned char *)buffer;
417     mmc_claim_host(card->host);
418     do {
419         ret = mmc_read_internal(card, blk, min(EMMC_BLOCK_SIZE, cnt), dst);
420         if (ret) {
421             pr_err("%s [%d] mmc_write_internal error\n", __func__, __LINE__);
422             break;
423         }
424         blk += EMMC_BLOCK_SIZE;
425         cnt -= EMMC_BLOCK_SIZE;
426         dst = (unsigned char *)buffer + MAX_EMMC_BLOCK_SIZE;
427     } while (cnt > 0);
428 
429     pr_info("%s:%d, read %s\n", __func__, __LINE__, (ret) ? "error" : "ok");
430 
431     mmc_release_host(card->host);
432     return ret;
433 }
434 EXPORT_SYMBOL(emmc_key_read);
435 
emmc_key_init(struct mmc_card * card)436 int emmc_key_init(struct mmc_card *card)
437 {
438     u64 addr = 0;
439     u32 size = 0;
440     u64 lba_start = 0, lba_end = 0;
441     int err = 0;
442     int bit = card->csd.read_blkbits;
443     struct unifykey_type *uk_type = NULL;
444     struct unifykey_storage_ops ops;
445 
446     pr_info("card key: card_blk_probe.\n");
447     emmckey_info = kmalloc(sizeof(*emmckey_info), GFP_KERNEL);
448     if (!emmckey_info) {
449         pr_info("%s:%d,kmalloc memory fail\n", __func__, __LINE__);
450         return -ENOMEM;
451     }
452     uk_type = kmalloc(sizeof(*uk_type), GFP_KERNEL);
453     if (!uk_type) {
454         err = -ENOMEM;
455         goto exit_err;
456     }
457     memset(emmckey_info, 0, sizeof(*emmckey_info));
458     emmckey_info->key_init = 0;
459 #ifdef KEY_BACKUP
460     size = EMMCKEY_AREA_PHY_SIZE + (512L * 2L);
461 #else
462     size = EMMCKEY_AREA_PHY_SIZE;
463 #endif
464     if (get_reserve_partition_off_from_tbl() < 0) {
465         err = -EINVAL;
466         goto exit_err1;
467     }
468     addr = get_reserve_partition_off_from_tbl() + EMMCKEY_RESERVE_OFFSET;
469     lba_start = addr >> bit;
470     lba_end = (addr + size) >> bit;
471     emmckey_info->key_init = 1;
472 
473     pr_info("%s:%d emmc key lba_start:0x%llx,lba_end:0x%llx\n", __func__, __LINE__, lba_start, lba_end);
474 
475     if (!emmckey_info->key_init) {
476         err = -EINVAL;
477 
478         pr_info("%s:%d,emmc key init fail\n", __func__, __LINE__);
479         goto exit_err1;
480     }
481     emmckey_info->keyarea_phy_addr = addr;
482     emmckey_info->keyarea_phy_size = size;
483     emmckey_info->lba_start = lba_start;
484     emmckey_info->lba_end = lba_end;
485     mmc_card_key = card;
486 #ifdef KEY_BACKUP
487     _key_init(card);
488 #endif
489     err = aml_emmc_key_check();
490     if (err) {
491         pr_info("%s:%d,emmc key check fail\n", __func__, __LINE__);
492         goto exit_err1;
493     }
494 
495     uk_type->storage_type = UNIFYKEY_STORAGE_TYPE_EMMC;
496     uk_type->ops = &ops;
497     uk_type->ops->read = emmc_key_read;
498     uk_type->ops->write = emmc_key_write;
499 
500     if (register_unifykey_types(uk_type)) {
501         err = -EINVAL;
502         pr_info("%s:%d,emmc key check fail\n", __func__, __LINE__);
503         goto exit_err1;
504     }
505     pr_info("emmc key: %s:%d ok.\n", __func__, __LINE__);
506 exit_err1:
507     kfree(uk_type);
508 exit_err:
509     kfree(emmckey_info);
510     return err;
511 }
512