/* * Copyright (C) 2003 BLADOX, s.r.o. All rights reserved. * * This file is part of an example program for Turbo. This example * program may be used, distributed and modified without limitation. * */ #include <config.h> #include <turbo/turbo.h> #include <stdlib.h> #include <string.h> #include "certs.h" #include "mycrypt.h" typedef struct _certs_mem { u16 certs_certs; u16 ecc_keys; u8 nr_ecc_keys; } certs_mem; SEdge *certs_certs; u16 ecc_keys; u8 nr_ecc_keys; u8 keys_clear; extern unsigned int s_mp_defprec; /* *INDENT-OFF* */ lc_char PROGMEM lc_Certs[] = { LC_EN ("Certs") LC_CZ ("Certifikaty") LC_END }; lc_char PROGMEM lc_Clear[] = { LC_EN ("Clear") LC_CZ ("Regenerovat") LC_END }; lc_char PROGMEM lc_Info[] = { LC_EN ("Info") LC_END }; /* *INDENT-ON* */ u8 PROGMEM t_Msg1_en[] = "Key cache cleared"; u8 PROGMEM t_s1[] = "Number of keys: "; u8 PROGMEM t_s2[] = "Cert name: "; u8 PROGMEM t_s3[] = "No key available.\nPlease wait."; u8 PROGMEM t_s4[] = "Cert deleted."; SNodeP certs_n; SNodeP certs_n_2_1; SNodeP certs_n_2_2; SNodeP certs_n_2_3; u8 certs_ctx (SCtx * ctx, u8 action) { if (action == APP_ENTER) { dbsp ("certs_ctx_create\n"); ctx->eE = certs_certs; } else if (action == APP_LEAVE) { dbsp ("certs_ctx_free\n"); ctx->eE = NULL; } } u8 certs_cert (SCtx * ctx, u8 action) { SEdge *e, *f; if (action == APP_ENTER) { ecc_cert *c; dbsp ("certs_cert_create\n"); c = rw (&ctx->n->p); spider_append_r (ctx, &certs_n_2_1); if (rb (&c->crypted) == 0) spider_append_r (ctx, &certs_n_2_2); //protect else spider_append_r (ctx, &certs_n_2_3); //unprotect } else if (action == APP_LEAVE) { dbsp ("certs_cert_free\n"); spider_clear_r (ctx); } return APP_OK; } u8 certs_new (SCtx * ctx, u8 action) { if (action == APP_ENTER) { u8 *v, *res; u16 j; u8 i, l; ecc_key *ekey; mp_int *from, *to; SEdge *e, *f; dbsp ("certs_new_ctx_run\n"); if (keys_clear == 1) ecc_clear_keys (); for (j = 0; j < nr_ecc_keys; j++) { ekey = ecc_keys + j * sizeof (ecc_key); i = rb (&ekey->ekey_status); l = rb (&ekey->ekey_ack); if (i == l && i == KEY_DONE) { i = j; goto END_3; } } res = display_text (t_s3, NULL); if (res == ENULL) return APP_END; // end return APP_BACK; END_3: dbsp ("C_K "); dbih (ekey); dbc ('\n'); v = emalloc (sizeof (ecc_cert)); to = emalloc (32); ww (&((ecc_cert *) v)->k, to); wb (&((ecc_cert *) v)->ekey_status, 0); wb (&((ecc_cert *) v)->crypted, 0); wb (&((ecc_cert *) v)->compress_y, rb (&ekey->compress_y)); for (i = 0; i < 32; i++) if (i < KEYSIZE + 1) wb ((u8 *) to + i, rb (&ekey->k[i])); else wb ((u8 *) to + i, 0); dbsp ("C_V "); dbih (v); dbc ('\n'); dbsp ("C_K "); dbih (to); dbc ('\n'); from = rw (&ekey->x.dp); dbsp ("C_F "); dbih (from); dbc ('\n'); e_mp_init (&((ecc_cert *) v)->x); wb (&((ecc_cert *) v)->x.used, rb (&ekey->x.used)); j = rb (&ekey->x.alloc); wb (&((ecc_cert *) v)->x.alloc, j); to = rw (&((ecc_cert *) v)->x.dp); dbsp ("C_T "); dbih (to); dbc ('\n'); j = j * 2; memcpy ((u8 *) to, (u8 *) from, j); from = rw (&ekey->y.dp); dbsp ("C_F "); dbih (from); dbc ('\n'); e_mp_init (&((ecc_cert *) v)->y); wb (&((ecc_cert *) v)->y.used, rb (&ekey->y.used)); j = rb (&ekey->y.alloc); wb (&((ecc_cert *) v)->y.alloc, j); to = rw (&((ecc_cert *) v)->y.dp); dbsp ("C_T "); dbih (to); dbc ('\n'); j = j * 2; memcpy ((u8 *) to, (u8 *) from, j); wb (&((ecc_cert *) v)->ekey_status, 1); wb (&ekey->ekey_status, KEY_START); reg_action (ACTION_IDLE_TASK); ekey = v; res = get_input (t_s2, 0, 0x0F, NULL, Q_GET_INPUT_ALPHABET); if (res == ENULL) return APP_END; // end if (res == NULL) return APP_BACK; // back { SNode *n; dbsp ("CB2_1_1\n"); j = 0; l = res[j] - 1; j++; //len j++; // coding v = emalloc (l + 3); wb (v, '<'); memcpy (v + 1, res + j, l); wb (v + 1 + l, '>'); wb (v + 2 + l, '\0'); n = emalloc (sizeof (SNode)); ww (&n->text, v); ww (&n->cb, certs_cert); ww (&n->p, ekey); dbsp ("CB2_1_2\n"); e = emalloc (sizeof (SEdge)); ww (&e->t, n); ww (&e->f, &certs_n); wb (&e->source, MEM_F_P | MEM_T_E); ww (&e->next, NULL); f = certs_certs; while (f && rw (&f->next)) { f = rw (&f->next); } dbsp ("CB2_1_3\n"); if (f) ww (&f->next, e); else { //f=e; ww (&(((certs_mem *) app_data ())->certs_certs), e); certs_certs = e; } } return APP_BACK; } } u8 certs_delete (SCtx * ctx, u8 action) { if (action == APP_ENTER) { u8 *res; ecc_cert *ekey; u16 j; SEdge *p, *c; res = display_text (t_s4, NULL); if (res == ENULL) return APP_END; // end ekey = ctx->n->p; efree (&ekey->x.dp); efree (&ekey->y.dp); efree (rw (&ekey->k)); efree (ekey); p = c = certs_certs; dbsp ("D_1\n"); while (c && rw (&c->t) != ctx->n) { p = c; c = rw (&c->next); } dbsp ("D_2\n"); if (c) ww (&p->next, rw (&c->next)); else ww (&p->next, NULL); dbsp ("D_3\n"); if (c == certs_certs) { certs_certs = rw (&c->next); } dbsp ("D_4\n"); efree (&c->t); efree (c); ctx->n = NULL; dbsp ("D_5\n"); return APP_BACK; } } u8 certs_protect (SCtx * ctx, u8 action) { if (action == APP_ENTER) { u8 *res, *key; u16 j, i, l; SNode *n; key = buf_A (); i = password (key, 16, NULL); if (i != APP_OK) return i; { u8 *k1, *k3; Twofish_key ak; ecc_cert *ekey; k3 = buf_A () + 16; k1 = emalloc (32); twofish_setup (key, 16, &ak); ekey = rw (&ctx->parent->f->p); n = rw (&ekey->k); dbsp ("E_n"); dbih (n); dbc ('\n'); dbsp ("E_k"); dbih (ekey); dbc ('\n'); dbsp ("E_k1"); dbih (k1); dbc ('\n'); memcpy (key, n, 16); // dbsp("P1_P "); for(i=0;i<16;i++){dbch(key[i]); dbc(' ');}dbc('\n'); twofish_ecb_encrypt (key, k3, &ak); memcpy (k1, k3, 16); // dbsp("P1_E "); for(i=0;i<16;i++){dbch(k3[i]); dbc(' ');}dbc('\n'); memcpy (key, (u8 *) n + 16, 16); // dbsp("P2_P "); for(i=0;i<16;i++){dbch(key[i]); dbc(' ');}dbc('\n'); twofish_ecb_encrypt (key, k3, &ak); memcpy ((u8 *) k1 + 16, k3, 16); // dbsp("P2_E "); for(i=0;i<16;i++){dbch(k3[i]); dbc(' ');}dbc('\n'); wb (&ekey->ekey_status, 0); ww (&ekey->k, k1); for (i = 0; i < 32; i++) wb ((u8 *) n + i, 0); efree (n); wb (&ekey->crypted, 1); wb (&ekey->ekey_status, 1); } return APP_BACK; } } u8 certs_unprotect (SCtx * ctx, u8 action) { if (action == APP_ENTER) { u8 *res, *key; u16 j, i, l; key = buf_A (); i = password (key, 16, NULL); if (i != APP_OK) return i; { u8 *k1, *k3; Twofish_key ak; ecc_cert *ekey; SNode *n; k3 = buf_A () + 16; k1 = emalloc (32); twofish_setup (key, 16, &ak); ekey = rw (&ctx->parent->f->p); n = rw (&ekey->k); memcpy (key, n, 16); // dbsp("P1_P "); for(i=0;i<16;i++){dbch(key[i]); dbc(' ');}dbc('\n'); twofish_ecb_decrypt (key, k3, &ak); memcpy (k1, k3, 16); // dbsp("P1_D "); for(i=0;i<16;i++){dbch(k3[i]); dbc(' ');}dbc('\n'); memcpy (key, (u8 *) n + 16, 16); // dbsp("P2_P "); for(i=0;i<16;i++){dbch(key[i]); dbc(' ');}dbc('\n'); twofish_ecb_decrypt (key, k3, &ak); memcpy ((u8 *) k1 + 16, k3, 16); // dbsp("P2_D "); for(i=0;i<16;i++){dbch(k3[i]); dbc(' ');}dbc('\n'); wb (&ekey->ekey_status, 0); ww (&ekey->k, k1); for (i = 0; i < 32; i++) wb ((u8 *) n + i, 0); efree (n); wb (&ekey->crypted, 0); wb (&ekey->ekey_status, 1); } return APP_BACK; } } u8 certs_clear (SCtx * ctx, u8 action) { if (action == APP_ENTER) { u8 *res; u16 j; ecc_clear_keys (); res = display_text (t_Msg1_en, NULL); if (res == ENULL) return APP_END; // end return APP_BACK; } } u8 certs_info (SCtx * ctx, u8 action) { if (action == APP_ENTER) { u8 *res; u8 *t, *r; u16 j; u8 e1, e2; ecc_key *ekey; if (keys_clear == 1) ecc_clear_keys (); t = malloc (128); r = sprints (t, t_s1); r = sprinti (r, nr_ecc_keys); r = sprintc (r, '\n'); for (j = 0; j < nr_ecc_keys; j++) { ekey = ecc_keys + j * sizeof (ecc_key); r = sprintc (r, 'K'); r = sprinti (r, j + 1); r = sprintc (r, ' '); e1 = rb (&ekey->ekey_status); e2 = rb (&ekey->ekey_ack); if (e1 != e2 || e1 == KEY_START) r = sprinti (r, 0); else if (e1 == KEY_DONE) r = sprinti (r, 100); else if (e1 == KEY_COMPRESS) r = sprinti (r, 99); else { e1 = rb (&ekey->ekey_j); e2 = rb (&ekey->ekey_j_ack); if (e1 != e2) r = sprinti (r, 0); else r = sprinti (r, (int) (100 * (0xBF - e1)) / 0xBF); } r = sprintc (r, '%'); r = sprintc (r, '\n'); } *r = '\0'; res = display_text (t, NULL); free (t); if (res == ENULL) return APP_END; // end return APP_BACK; } } SNodeP certs_n = { lc_Certs, certs_ctx }; SNodeP certs_n_1 = { LC_NEW, certs_new }; SNodeP certs_n_2_1 = { LC_DELETE, certs_delete }; SNodeP certs_n_2_2 = { LC_PROTECT, certs_protect }; SNodeP certs_n_2_3 = { LC_UNPROTECT, certs_unprotect }; SNodeP certs_n_3 = { lc_Clear, certs_clear }; SNodeP certs_n_4 = { lc_Info, certs_info }; SEdgeP certs_edges_p[] = { {&certs_n, &certs_n_1}, // Certs->New {&certs_n, &certs_n_3}, // Certs->Clear {&certs_n, &certs_n_4}, // Certs->Info NULL }; void certs () { SCtx *c = spider_init (); if (c == NULL) return; c->n = &certs_n; c->eP = &certs_edges_p; spider (c); } extern void certs_idle_task_2 (void); extern u8 PROGMEM ecc192_order[]; u8 PROGMEM t_Sign_mime[] = "sign"; void sign_q_sms (u8 * s) { u8 *tmp = NULL, *res, *q; u8 *t; u8 j; u8 i, k; ecc_key *ekey; ecc_cert *ecert; SEdge *e = certs_certs; mp_int b, p, pub_k, key_k; u16 seq; // test if cert && key, otherwise 9000 if (e == NULL) goto END_1; if (keys_clear == 1) { ecc_clear_keys (); goto END_1; } for (i = 0; i < nr_ecc_keys; i++) { ekey = ecc_keys + i * sizeof (ecc_key); k = rb (&ekey->ekey_status); if (k == rb (&ekey->ekey_ack) && k == KEY_DONE) goto END_3; } goto END_1; END_3: ecert = rw (&e->t); ecert = rw (&((SNode *) ecert)->p); dbsp ("CERT "); dbih (ecert); dbc ('\n'); if (mp_init_multi (&b, &p, &pub_k, &key_k, NULL) != MP_OKAY) goto END_1; dbsp ("S_0\n"); db_malloc (); if ((tmp = malloc (32)) == NULL) goto CRYPT_ERROR; dbsp ("S_0_0\n"); db_malloc (); res = rw (&ecert->k); dbsp ("CERT_K "); dbih (res); dbc ('\n'); memcpy (tmp, res, 32); // if protected -> unprotect if (mp_read_raw (&key_k, tmp, KEYSIZE + 1) != MP_OKAY) goto CRYPT_ERROR; dbsp ("KEY_K: "); out_mp_8 (&key_k); // dbsp("KEY_K ");dbih(&ekey->k);dbc('\n'); memcpy (tmp, &ekey->k, KEYSIZE + 1); if (mp_read_raw (&pub_k, tmp, KEYSIZE + 1) != MP_OKAY) goto CRYPT_ERROR; // dbsp("S_0_1\n");db_malloc(); dbsp ("PUB_K: "); out_mp_8 (&pub_k); // hash -> tmp q = skip_head (s); #define HASH_LEN 20 dbsp ("HASH_LEN "); dbch (*q); dbc ('\n'); tmp[0] = 0; for (i = 1; i < HASH_LEN + 1; i++) if (i < *q + 1) tmp[i] = *(q + i); else tmp[i] = 0; // md is hash if (mp_read_raw (&b, tmp, HASH_LEN + 1) != MP_OKAY) goto CRYPT_ERROR; dbsp ("B: "); out_mp_8 (&b); free (tmp); tmp = NULL; if (mp_read_radix (&p, ecc192_order, 10) != MP_OKAY) goto CRYPT_ERROR; // dbsp("S_0_2\n");db_malloc(); dbsp ("P: "); out_mp_8 (&p); dbsp ("S_1\n"); db_malloc (); /* find b = (m - x)/k */ if (mp_invmod (&pub_k, &p, &pub_k) != MP_OKAY) goto CRYPT_ERROR; /* k = 1/k */ dbsp ("X_1: "); out_mp_8 (&pub_k); dbsp ("S_2\n"); db_malloc (); if (mp_submod (&b, &key_k, &p, &b) != MP_OKAY) goto CRYPT_ERROR; /* b = m - x */ dbsp ("X_2: "); out_mp_8 (&b); dbsp ("S_3\n"); db_malloc (); if (mp_mulmod (&b, &pub_k, &p, &b) != MP_OKAY) goto CRYPT_ERROR; /* b = (m - x)/k */ dbsp ("X_3: "); out_mp_8 (&b); dbsp ("S_4\n"); db_malloc (); mp_clear (&pub_k); mp_clear (&p); mp_clear (&key_k); dbsp ("S_5\n"); db_malloc (); t = tpdu_seek (s, T_SMS_AA); if ((tmp = malloc (111)) == NULL) goto END_2; q = create_head_a (tmp, s); *q = ECC_192; q++; dbsp ("I_1 "); dbih (&ecert->x); dbc ('\n'); // store ecert->x q += mp_store_e (q, &ecert->x); // ecert->compress_y *q = rb (&ecert->compress_y); q++; dbsp ("I_3 "); dbih (&ekey->x); dbc ('\n'); // ekey->x q += mp_store_e (q, &ekey->x); // ekey->compress_y *q = rb (&ekey->compress_y); q++; // size of b q += mp_store (q, &b); wb (&ekey->ekey_ack, KEY_START); dbsp ("SIG: "); for (j = 0; j < (q - tmp); j++) { dbch (tmp[j]); dbc (' '); } dbc ('\n'); // key = start, keys_ok = false send_sms (tmp, q - tmp, t, MSISDN_SMS, tsms_dcs (), tsms_pid (), NULL, NULL); goto END_2; CRYPT_ERROR: dbsp ("S_FREE\n"); db_malloc (); mp_clear (&key_k); mp_clear (&pub_k); mp_clear (&p); END_2: dbsp ("S_FREE_1\n"); db_malloc (); mp_clear (&b); END_1: dbsp ("S_END_1\n"); db_malloc (); if (tmp) free (tmp); } void sign_a_sms (u8 * s) { // rec all sms info, deco and rest dbsp ("REC_SIGN_A_SMS\n"); } void sign () { u8 *tmp, *ms, *res, *q; u8 l, j, i; res = msisdn (NULL); if (res != ENULL && res != NULL) { #define LEN_H 20 #ifdef TEST_VECT static u8 PROGMEM h[LEN_H] = { 0xAA, 0xF4, 0xC6, 0x1D, 0xDC, 0xC5, 0xE8, 0xA2, 0xDA, 0xBE, 0xDE, 0x0F, 0x3B, 0x48, 0x2C, 0xD9, 0xAE, 0xA9, 0x43, 0x4D }; #else u8 PROGMEM h[LEN_H]; xrand (&h[0]); xrand (&h[8]); xrand (&h[12]); #endif ms = msisdncpy (res, MSISDN_ADN, MEM_R); tmp = buf_B (); q = create_head_q (tmp, t_Sign_mime, ms, MSISDN_ADN); *q = LEN_H; q++; #ifdef TEST_VECT memcpy (q, h, LEN_H); q += LEN_H; #else memcpy (q, h, LEN_H); q += LEN_H; #endif send_sms (tmp, q - tmp, ms, MSISDN_ADN, tsms_dcs (), tsms_pid (), NULL, NULL); if (ms) free (ms); } } lc_char PROGMEM lc_Sign[] = { LC_EN ("Sign") LC_END }; void action_menu (Menu_selection_data * x) { if (x->item == 0) { certs (); } else sign (); } void turbo_handler (u8 action, void *data) { dbsp ("CERTS "); dbch (action); dbc ('\n'); switch (action) { case ACTION_APP_REGISTER: reg_sms_tag (locale (lc_Sign), t_Sign_mime, SMS_TYPE_QA); { certs_mem *p = emalloc (sizeof (certs_mem)); ecc_key *e; u8 i; e = emalloc (sizeof (ecc_key) * NR_ECC_KEYS); for (i = 0; i < NR_ECC_KEYS; i++) { wb (&e[i].ekey_status, KEY_START); e_mp_init (&e[i].x); e_mp_init (&e[i].y); } ww (&p->certs_certs, NULL); wb (&p->nr_ecc_keys, NR_ECC_KEYS); ww (&p->ecc_keys, e); reg_app_data (p); } break; case ACTION_APP_UNREGISTER: efree (ecc_keys); efree (certs_certs); break; case ACTION_APP_INIT: { keys_clear = 1; certs_mem *p = app_data (); certs_certs = rw (&p->certs_certs); nr_ecc_keys = rb (&p->nr_ecc_keys); ecc_keys = rw (&p->ecc_keys); reg_action (ACTION_IDLE_TASK); s_mp_defprec = MP_DEFPREC; } break; case ACTION_INSERT_MENU: insert_menu (locale (lc_Certs)); insert_menu (locale (lc_Sign)); break; case ACTION_MENU_SELECTION: stk_thread (action_menu, data); break; case ACTION_IDLE_TASK: certs_idle_task_2 (); break; case ACTION_SMS_Q: stk_thread (sign_q_sms, data); break; case ACTION_SMS_A: stk_thread (sign_a_sms, data); break; default: break; } }
Copyright © 2004-2006 BLADOX | Turbo version 1.2
|