Main Page | Modules | Data Structures | File List | Data Fields | Globals | Related Pages | Examples

certs.c

Example of idle task.
/*
 * 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