Beispiel #1
0
struct item* deserialize(char* buffer, int size)
  /*@ requires [?f0]world(?pub, ?key_clsfy) &*&
               [?f1]chars(buffer, size, ?cs); @*/
  /*@ ensures  [f0]world(pub, key_clsfy) &*&
               [f1]chars(buffer, size, cs) &*&
               item(result, ?i, pub) &*& [_]pub(i); @*/
{
  if (size <= MINIMAL_STRING_SIZE)
    abort_crypto_lib("Found corrupted item during deserialization");

  struct item* item = malloc(sizeof(struct item));
  if (item == 0){abort_crypto_lib("malloc of item failed");}

  //@ open [f0]world(pub, key_clsfy);
  //@ public_chars(buffer, size);
  //@ close [f0]world(pub, key_clsfy);
  item->size = size;
  item->content = malloc_wrapper(item->size);
  //@ assert item->content |-> ?cont;
  //@ chars_to_crypto_chars(buffer, size);
  //@ assert [f1]crypto_chars(normal, buffer, size, ?ccs);
  memcpy(item->content, buffer, (unsigned int) size);
  //@ get_forall_t<char>();
  //@ get_forall_t<list<char> >();
  parse_item(buffer, size);
  //@ retreive_proof_obligations();
  //@ deserialize_item(ccs);
  //@ leak proof_obligations(pub);
  //@ assert [_]item_constraints(?i, ccs, pub) &*& [_]pub(i);
  //@ cs_to_ccs_crypto_chars(cont, cs);
  //@ cs_to_ccs_crypto_chars(buffer, cs);
  //@ chars_to_secret_crypto_chars(cont, size);
  //@ close item(item, i, pub);
  return item;
}
Beispiel #2
0
struct item *create_hash(struct item *payload)
  /*@ requires [?f0]world(?pub, ?key_clsfy) &*&
               [?f1]item(payload, ?pay, pub); @*/
  /*@ ensures  [f0]world(pub, key_clsfy) &*&
               [f1]item(payload, pay, pub) &*& item(result, ?hash, pub) &*& 
               col || hash == hash_item(some(pay)); @*/
{
  //@ open [f1]item(payload, pay, pub);
  //@ open [_]item_constraints(pay, ?pay_cs, pub);
  //@ assert [f1]payload->content |-> ?p_cont &*& [f1]payload->size |-> ?p_size;
  struct item* hash = malloc(sizeof(struct item));
  if (hash == 0){abort_crypto_lib("malloc of item failed");}
  
  hash->size = TAG_LENGTH + HASH_SIZE;
  hash->content = malloc_wrapper(hash->size);
  write_tag(hash->content, TAG_HASH);
  
  if (payload->size < MINIMAL_STRING_SIZE)
    {abort_crypto_lib("Payload of hash was to small");}
  sha512(payload->content, (unsigned int) payload->size, hash->content + TAG_LENGTH, 0);
  
  //@ open [f0]world(pub, key_clsfy);  
  //@ assert hash->content |-> ?cont &*& hash->size |-> ?size;
  //@ public_chars(cont, TAG_LENGTH);
  //@ assert chars(cont, TAG_LENGTH, ?cs_tag);
  //@ assert cs_tag == full_tag(TAG_HASH);
  //@ open cryptogram(cont + TAG_LENGTH, HASH_SIZE, ?cs_cont, ?h_cg);
  //@ assert h_cg == cg_hash(pay_cs);
  //@ item h = hash_item(some(pay));
  //@ close ic_cg(h)(cs_cont, h_cg);
  //@ list<char> cs = append(cs_tag, cs_cont);
  //@ if (col) public_chars(cont + TAG_LENGTH, HASH_SIZE);
  //@ if (col) public_generated_join(polarssl_pub(pub), cs_tag, cs_cont);  
  //@ if (col) chars_to_secret_crypto_chars(cont + TAG_LENGTH, HASH_SIZE);
  //@ chars_to_secret_crypto_chars(cont, TAG_LENGTH);
  //@ crypto_chars_join(cont);
  //@ close [f0]world(pub, key_clsfy);
  //@ close ic_parts(h)(cs_tag, cs_cont);
  //@ WELL_FORMED(cs_tag, cs_cont, TAG_HASH)
  //@ close well_formed_item_chars(h)(pay_cs);
  //@ leak well_formed_item_chars(h)(pay_cs);
  //@ close item_constraints(h, cs, pub);
  //@ leak item_constraints(h, cs, pub);
  //@ close item(hash, h, pub);
  
  return hash;
  //@ close [f1]item(payload, pay, pub);
}
Beispiel #3
0
void check_is_hash(struct item *item)
  //@ requires [?f]world(?pub, ?key_clsfy) &*& item(item, ?i, pub);
  //@ ensures  [f]world(pub, key_clsfy) &*& item(item, i, pub) &*& i == hash_item(_);
{
  if (!is_hash(item))
    abort_crypto_lib("Presented item is not a hash");
}
Beispiel #4
0
void send_data(struct network_status *net_stat)
  /*@ requires [?f0]world(?pub, ?key_clsfy) &*&
               proof_obligations(pub) &*&
               network_status(net_stat) &*&
               principal(?principal, ?count1) &*&
               true == bad(principal); @*/
  /*@ ensures  [f0]world(pub, key_clsfy) &*&
               proof_obligations(pub) &*&
               network_status(net_stat) &*&
               principal(principal, ?count2); @*/
{
  int data_size = random_int_();
  if (data_size > MIN_RANDOM_SIZE)
  {
    char* data = malloc((int) data_size);
    if (data == 0) abort_crypto_lib("malloc failed");
    random_buffer_(data, data_size);
    struct item *item = create_data_item(data, data_size);
    //@ assert item(item, ?i, pub) &*& i == data_item(?d);
    free(data);
    //@ open proof_obligations(pub);
    //@ assert is_public_data(?proof, pub);
    //@ proof(i);
    //@ close proof_obligations(pub);
    network_send(net_stat, item);
    item_free(item);
  }
}
void check_valid_symmetric_encrypted_item_size(int size)
  //@ requires true;
  //@ ensures  size > TAG_LENGTH + GCM_IV_SIZE;
{
  if (size <= TAG_LENGTH + GCM_KEY_SIZE)
    abort_crypto_lib("Illegal size for symmetric encrypted item");
}
Beispiel #6
0
int create_principal(struct keypair** keypair)
  /*@ requires world(?pub, ?key_clsfy) &*&
               pointer(keypair, _) &*&
               principals_created(?count); @*/
  /*@ ensures  world(pub, key_clsfy) &*&
               principals_created(result) &*&
               result == count + 1 &*&
               principal(result, 1) &*&
               pointer(keypair, ?p_keypair) &*&
               keypair(p_keypair, result, 1, 0, pub); @*/
{
  //@ open principals_created(count);
  //@ principal_create();
  
  if (counter >= INT_MAX - 1)
  {
    abort_crypto_lib("To many principals generated");
  }
  
  counter++;
  //@ close keypair_request(count + 1, 0);
  struct keypair *k = create_keypair(counter);
  *keypair = k;
  struct item *key = keypair_get_public_key(k);
  register_public_key(counter, key);
  item_free(key);
  
  return counter;
  //@ close principals_created(count + 1);
}
Beispiel #7
0
struct item *get_public_key(int participant)
  //@ requires [?f]world(?pub, ?key_clsfy);
  /*@ ensures  [f]world(pub, key_clsfy) &*&
               item(result, public_key_item(participant, 1), pub);
  @*/
{
  //@ open [f]world(pub, key_clsfy);
  //@ open [f]key_registry_initialized(pub);

  if (participant < 1)
    abort_crypto_lib("Participant does not exist");

  struct item *result = 0;
  struct key_registry* current = registered_keys;
  while(current != 0 && result == 0)
   /*@ requires  [f]key_registry(current, pub) &*&
                 result == 0 ?
                   true
                 :
                   item(result, public_key_item(participant, 1), pub); @*/
   /*@ ensures   [f]key_registry(old_current, pub) &*&
                 result == 0 ?
                   true
                 :
                   item(result, public_key_item(participant, 1), pub); @*/
  {
    //@ open [f]key_registry(current, pub);
    if (current->participant == participant)
    {
      result = item_clone(current->pub_key);
      //@ close [f]key_registry(old_current, pub);
      break;
    }
    current = current->next;

    //@ recursive_call();
    //@ close [f]key_registry(old_current, pub);
  }

  if (result == 0)
    abort_crypto_lib("Participant does not exist");

  return result;
  //@ close [f]key_registry_initialized(pub);
  //@ close [f]world(pub, key_clsfy);
}
void check_is_asymmetric_encrypted(struct item *item)
  //@ requires [?f]world(?pub, ?key_clsfy) &*& item(item, ?i, pub);
  /*@ ensures  [f]world(pub, key_clsfy) &*& item(item, i, pub) &*&
               i == asymmetric_encrypted_item(_, _, _, _); @*/
{
  if (!is_asymmetric_encrypted(item))
    abort_crypto_lib("Presented item is not an asymmetric encrypted item");
}
Beispiel #9
0
void check_is_pair(struct item *item)
  //@ requires [?f]world(?pub, ?key_clsfy) &*& item(item, ?p, pub);
  /*@ ensures  [f]world(pub, key_clsfy) &*& item(item, p, pub) &*&
               p == pair_item(_, _); @*/
{
  if (!is_pair(item))
    abort_crypto_lib("Presented item is not a pair item");
}
Beispiel #10
0
void *malloc_wrapper(int size)
  //@ requires 0 <= size;
  /*@ ensures  result != 0 &*&
               malloc_block(result, size) &*& chars(result, size, ?cs) &*&
               true == ((char *)0 < result &&
               result + size <= (char *)UINTPTR_MAX);
  @*/
{
  if (size > MAX_PACKAGE_SIZE)
    abort_crypto_lib("Requested humongous malloc!!!!!!!!");

  void* result = malloc(size);
  if (result == 0)
    abort_crypto_lib("Malloc failed");

  return result;
}
Beispiel #11
0
struct item* item_clone(struct item* item)
  //@ requires [?f]item(item, ?i, ?pub);
  /*@ ensures  [f]item(item, i, pub) &*& 
               item(result, i, pub) &*& result != 0; @*/
{
  //@ open [f]item(item, i, pub);
  struct item* clone = malloc(sizeof(struct item));
  if (clone == 0){abort_crypto_lib("malloc of item failed");}
  clone->size = item->size;
  clone->content = malloc_wrapper(clone->size);
  memcpy(clone->content, item->content, (unsigned int) clone->size);

  return clone;
  //@ close [f]item(item, i, pub);
  //@ close item(clone, i, pub);
}
Beispiel #12
0
void register_public_key(int participant, struct item *key)
  /*@ requires world(?pub, ?key_clsfy) &*&
               item(key, public_key_item(participant, 1), pub); @*/
  /*@ ensures  world(pub, key_clsfy) &*&
               item(key, public_key_item(participant, 1), pub); @*/
{
  struct item* clone = item_clone(key);

  //@ open world(pub, key_clsfy);
  struct key_registry *kr = malloc(sizeof(struct key_registry));
  if (kr == 0) {abort_crypto_lib("malloc failed");}

  //@ open key_registry_initialized(pub);
  kr->participant = participant;
  kr->pub_key = clone;
  kr->next = registered_keys;
  registered_keys = kr;

  //@ assert pointer(&registered_keys, ?head);
  //@ close key_registry(head, pub);
  //@ close key_registry_initialized(pub);
  //@ close world(pub, key_clsfy);
}
Beispiel #13
0
void pair_get_components(struct item* pair,
                         struct item** firstp, struct item** secondp)
  /*@ requires [?f]world(?pub, ?key_clsfy) &*& item(pair, ?p, pub) &*&
               p == pair_item(?f0, ?s0) &*&
               pointer(firstp, _) &*& pointer(secondp, _); @*/
  /*@ ensures  [f]world(pub, key_clsfy) &*& item(pair, p, pub) &*&
               pointer(firstp, ?fp) &*& pointer(secondp, ?sp) &*&
                item(fp, ?f1, pub) &*& item(sp, ?s1, pub) &*&
               col ? true : f0 == f1 && s0 == s1; @*/
{
  char* temp;

  check_is_pair(pair);
  //@ open item(pair, p, pub);
  //@ assert pair->content |-> ?cont &*& pair->size |-> ?size;
  //@ assert crypto_chars(secret, cont, size, ?cs);
  //@ open [_]item_constraints(p, cs, pub);
  //@ assert [_]ic_parts(p)(?cs_tag, ?cs_cont);
  //@ take_append(TAG_LENGTH, cs_tag, cs_cont);
  //@ drop_append(TAG_LENGTH, cs_tag, cs_cont);
  //@ assert [_]ic_pair(p)(?cs_f, ?cs_s);
  
  struct item *first  = malloc(sizeof(struct item));
  struct item *second = malloc(sizeof(struct item));
  if (first == 0 || second == 0){abort_crypto_lib("malloc of item failed");}

  temp = pair->content;
  //@ crypto_chars_split(cont, TAG_LENGTH);
  //@ if (col) public_generated_split(polarssl_pub(pub), cs, TAG_LENGTH);
  //@ assert crypto_chars(secret, temp, TAG_LENGTH, cs_tag);
  //@ assert crypto_chars(secret, temp + TAG_LENGTH, size - TAG_LENGTH, cs_cont);
  //@ assert cs_tag == full_tag(TAG_PAIR);
  //@ assert cs == append(cs_tag, cs_cont);
  //@ switch(cs_tag) {case cons(c0, cs0): case nil: assert false;}
  //@ assert cs_tag == cons(TAG_PAIR, _);
  

  temp = temp + TAG_LENGTH;
  if (pair->size <= TAG_LENGTH + (int) sizeof(int))
    abort_crypto_lib("Found corrupted pair item 1");

  //@ open [f]world(pub, key_clsfy);
  //@ crypto_chars_split(temp, sizeof(int));
  //@ if (col) public_generated_split(polarssl_pub(pub), cs_cont, sizeof(int));
  //@ assert crypto_chars(secret, temp, sizeof(int), ?cs_size_f);
  //@ assert crypto_chars(secret, temp + sizeof(int), size - TAG_LENGTH - sizeof(int), ?cs_p);
  //@ take_append(sizeof(int), cs_size_f, cs_p);
  //@ drop_append(sizeof(int), cs_size_f, cs_p);
  //@ public_crypto_chars(temp, sizeof(int));
  //@ chars_to_integer(temp);
  first->size = *((int*) (void*) temp);
  second->size = pair->size - TAG_LENGTH - (int) sizeof(int) - first->size;
  //@ assert first->size |-> ?size_f &*& second->size |-> ?size_s;
  if (first->size <= TAG_LENGTH ||
      pair->size - TAG_LENGTH - (int) sizeof(int) <= first->size)
    abort_crypto_lib("Found corrupted pair item 2");
  //@ integer_to_chars(temp);
  temp = temp + (int) sizeof(int);
  //@ assert cs_cont == append(cs_size_f, cs_p);
  //@ append_assoc(cs_cont, cs_size_f, cs_p);
  //@ crypto_chars_split(temp, first->size);
  //@ if (col) public_generated_split(polarssl_pub(pub), cs_p, first->size);
  //@ take_append(size_f, cs_f, cs_s);
  //@ drop_append(size_f, cs_f, cs_s);
  //@ assert crypto_chars(secret, temp, size_f, cs_f);
  //@ assert crypto_chars(secret, temp + size_f, size_s, cs_s);
  //@ assert cs_p == append(cs_f, cs_s);
  first->content = malloc_wrapper(first->size);
  if (first->size <= MINIMAL_STRING_SIZE)
    abort_crypto_lib("Found corrupted pair item 3");
  memcpy(first->content, temp, (unsigned int) first->size);
  temp = temp + first->size;
  if (second->size <= MINIMAL_STRING_SIZE)
    abort_crypto_lib("Found corrupted pair item 4");
  second->content = malloc_wrapper(second->size);
  memcpy(second->content, temp, (unsigned int) second->size);
  //@ crypto_chars_join(cont + TAG_LENGTH + sizeof(int));
  //@ chars_to_secret_crypto_chars(cont + TAG_LENGTH, sizeof(int));
  //@ crypto_chars_join(cont + TAG_LENGTH);
  //@ assert first->content |-> ?cont_f &*& second->content |-> ?cont_s;
  //@ assert crypto_chars(secret, cont_f, size_f, cs_f);
  //@ assert crypto_chars(secret, cont_s, size_s, cs_s);
  //@ assert size_f == int_of_chars(cs_size_f);
  //@ assert chars_of_unbounded_int(size_f) == cs_size_f;
  //@ assert length(cs_f) == size_f;
  //@ assert [_]item_constraints(f0, ?cs_f0, pub);
  //@ assert [_]item_constraints(s0, ?cs_s0, pub);
  /*@ drop_append(sizeof(int), chars_of_int(length(cs_f0)),
                  append(cs_f0, cs_s0)); @*/
  /*@ take_append(sizeof(int), chars_of_int(length(cs_f0)),
                  append(cs_f0, cs_s0)); @*/
  //@ drop_append(length(cs_f0), cs_f0, cs_s0);
  //@ take_append(length(cs_f0), cs_f0, cs_s0);
  //@ close item(first, f0, pub);
  //@ close item(second, s0, pub);
  //@ close item(pair, pair_item(f0, s0), pub);

  *firstp = first;
  *secondp = second;
  //@ close [f]world(pub, key_clsfy);
}
struct item *asymmetric_encryption(struct item *key, struct item *payload)
  /*@ requires [?f]world(?pub, ?key_clsfy) &*&
               principal(?principal1, ?count1) &*&
               item(payload, ?pay, pub) &*& item(key, ?k, pub) &*&
               k == public_key_item(?principal2, ?count2); @*/
  /*@ ensures  [f]world(pub, key_clsfy) &*&
               principal(principal1, count1 + 1) &*&
               item(payload, pay, pub) &*& item(key, k, pub) &*&
               item(result, ?enc, pub) &*&
               col ? true :
                 enc == asymmetric_encrypted_item(principal2, count2,
                                                  some(pay), ?ent); @*/
{
  debug_print("ASYM ENCRYPTING:\n");
  print_item(payload);

  struct item* result;
  result = malloc(sizeof(struct item));
  if (result == 0) abort_crypto_lib("Malloc failed");

  {
    pk_context context;
    unsigned int olen;
    char output[MAX_PACKAGE_SIZE];

    // Key
    //@ close pk_context(&context);
    //@ open [f]world(pub, key_clsfy);
    pk_init(&context);
    //@ close [f]world(pub, key_clsfy);
    set_public_key(&context, key);
    //@ open [f]world(pub, key_clsfy);
    /*@ assert pk_context_with_key(&context, pk_public,
                                   ?principal, ?count, RSA_BIT_KEY_SIZE); @*/
    //@ assert col || principal == principal2;
    //@ assert col || count == count2;

    // Encryption
    //@ open item(payload, pay, pub);
    //@ assert [_]item_constraints(pay, ?pay_cs, pub);
    if (payload->size > RSA_KEY_SIZE)
      abort_crypto_lib("Asymmetric encryption failed: incorrect sizes");
    void *random_state = nonces_expose_state();
    //@ close random_state_predicate(havege_state_initialized);
    /*@ produce_function_pointer_chunk random_function(
                      asym_enc_havege_random_stub)
                     (havege_state_initialized)(state, out, len) { call(); } @*/
    //@ open principal(principal1, count1);
    if(pk_encrypt(&context, payload->content, (unsigned int) payload->size,
                  output, &olen, MAX_PACKAGE_SIZE,
                  asym_enc_havege_random_stub, random_state) != 0)
      abort_crypto_lib("Encryption failed");
    //@ close principal(principal1, count1 + 1);
    //@ open cryptogram(output, ?enc_length, ?enc_cs, ?enc_cg);
    //@ assert enc_cg == cg_asym_encrypted(principal, count, pay_cs, ?ent);
    //@ assert u_integer(&olen, enc_length);
    //@ assert enc_length > 0 &*& enc_length < MAX_PACKAGE_SIZE;
    //@ assert enc_length > 0 &*& enc_length <= RSA_SERIALIZED_KEY_SIZE;
    nonces_hide_state(random_state);
    //@ pk_release_context_with_key(&context);
    pk_free(&context);
    //@ open pk_context(&context);
    //@ close [f]world(pub, key_clsfy);

    // Create item
    result->size = TAG_LENGTH + (int) olen;
    result->content = malloc(result->size);
    if (result->content == 0) {abort_crypto_lib("Malloc failed");}
    write_tag(result->content, TAG_ASYMMETRIC_ENC);
    //@ assert result->content |-> ?cont &*& result->size |-> ?size;
    if (olen < MINIMAL_STRING_SIZE) {abort_crypto_lib("Asymmetric encryption failed: to small");}
    memcpy(result->content + TAG_LENGTH, output, olen);
    //@ assert chars(cont, TAG_LENGTH, ?cs_tag);
    //@ public_chars(cont, TAG_LENGTH);
    //@ chars_to_secret_crypto_chars(cont, TAG_LENGTH);
    //@ assert cs_tag == full_tag(TAG_ASYMMETRIC_ENC);
    //@ crypto_chars_join(cont);

    //@ item enc = asymmetric_encrypted_item(principal, count, some(pay), ent);
    //@ list<char> cs = append(cs_tag, enc_cs);
    //@ WELL_FORMED(cs_tag, enc_cs, TAG_ASYMMETRIC_ENC)
    //@ close ic_parts(enc)(cs_tag, enc_cs);
    //@ close ic_cg(enc)(enc_cs, enc_cg);
    /*@ if (col)
      {
        crypto_chars_to_chars(cont, size);
        public_chars(cont, size);
        chars_to_secret_crypto_chars(cont, size);
        public_generated_split(polarssl_pub(pub), cs, TAG_LENGTH);
      }
    @*/
    //@ well_formed_item_constraints(pay, enc);
    //@ close item_constraints(enc, cs, pub);
    //@ leak item_constraints(enc, cs, pub);
    //@ close item(result, enc, pub);
    zeroize(output, (int) olen);
    //@ chars_join(output);
    //@ close item(payload, pay, pub);
  }

  debug_print("ENCRYPTING RESULT:\n");
  print_item(result);

  return result;
}
struct item *asymmetric_decryption(struct item *key, struct item *item, char tag)
  /*@ requires [?f]world(?pub, ?key_clsfy) &*& true == valid_tag(tag) &*&
               principal(?principal1, ?count1) &*&
               item(item, ?enc, pub) &*& item(key, ?k, pub) &*&
                 enc == asymmetric_encrypted_item(?principal2, ?count2,
                                                  ?pay, ?ent) &*&
               k == private_key_item(?principal3, ?count3); @*/
  /*@ ensures  [f]world(pub, key_clsfy) &*&
               principal(principal1, count1 + 1) &*&
               item(item, enc, pub) &*& item(key, k, pub) &*&
               item(result, ?dec, pub) &*& tag_for_item(dec) == tag &*&
               col ? 
                 [_]pub(dec) 
               : principal2 != principal3 || count2 != count3 ? 
                 true == key_clsfy(principal3, count3, false) &*& 
                 [_]pub(dec) 
               :
                 switch(pay)
                 {
                   case some(dec2):
                     return dec == dec2;
                   case none:
                     return false;
                 }; @*/
{
  struct item* result = 0;
  debug_print("DECRYPTING:\n");
  print_item(item);
  check_is_asymmetric_encrypted(item);

  {
    pk_context context;
    unsigned int olen;
    char output[MAX_PACKAGE_SIZE];

    // Key
    //@ close pk_context(&context);
    //@ open [f]world(pub, key_clsfy);
    pk_init(&context);
    //@ close [f]world(pub, key_clsfy);
    set_private_key(&context, key);
    //@ open [f]world(pub, key_clsfy);
    /*@ assert pk_context_with_key(&context, pk_private,
                                   ?principal, ?count, RSA_BIT_KEY_SIZE); @*/

    // Decryption
    //@ open item(item, enc, pub);
    /*@ assert enc == asymmetric_encrypted_item(principal2, count2,
                                                pay, ent); @*/
    //@ open [_]item_constraints(enc, ?enc_cs, pub);
    //@ assert [_]ic_parts(enc)(?enc_tag, ?enc_cont);
    //@ assert enc_cs == append(enc_tag, enc_cont);
    //@ open [_]ic_cg(enc)(_, ?enc_cg);
    //@ assert enc_cg == cg_asym_encrypted(principal2, count2, ?cs_pay, ent);
    if (item->size - TAG_LENGTH > RSA_KEY_SIZE ||
        item->size - TAG_LENGTH < MINIMAL_STRING_SIZE)
      abort_crypto_lib("Asymmetric decryption failed: incorrect sizes");
    //@ assert item->content |-> ?i_cont &*& item->size |-> ?i_size;
    //@ crypto_chars_split(i_cont, TAG_LENGTH);
    //@ drop_append(TAG_LENGTH, enc_tag, enc_cont);
    //@ assert crypto_chars(secret, i_cont + TAG_LENGTH, i_size - TAG_LENGTH, enc_cont);
    //@ if (col) enc_cg = chars_for_cg_sur(enc_cont, tag_asym_encrypted);
    //@ if (col) public_crypto_chars_extract(i_cont + TAG_LENGTH, enc_cg);
    //@ close cryptogram(i_cont + TAG_LENGTH, i_size - TAG_LENGTH, enc_cont, enc_cg);
    void *random_state = nonces_expose_state();
    //@ close random_state_predicate(havege_state_initialized);
    /*@ produce_function_pointer_chunk random_function(
                      asym_enc_havege_random_stub)
                     (havege_state_initialized)(state, out, len) { call(); } @*/
    //@ open principal(principal1, count1);
    //@ structure s = known_value(0, full_tag(tag));
    //@ close decryption_pre(false, false, principal1, s, enc_cont);
    if(pk_decrypt(&context, item->content + TAG_LENGTH,
                  (unsigned int) item->size - TAG_LENGTH,
                  output, &olen, MAX_PACKAGE_SIZE,
                  asym_enc_havege_random_stub, random_state) != 0)
      abort_crypto_lib("Decryption failed");
    /*@ open decryption_post(false, ?garbage, principal1, 
                             s, ?p_key, ?c_key, ?cs_out); @*/
    //@ assert u_integer(&olen, ?size_out);
    //@ pk_release_context_with_key(&context);
    //@ open cryptogram(i_cont + TAG_LENGTH, i_size - TAG_LENGTH, enc_cont, enc_cg);
    pk_free(&context);
    //@ open pk_context(&context);
    nonces_hide_state(random_state);
    //@ assert chars((void*)output + size_out, MAX_PACKAGE_SIZE - size_out, ?cs_rest);
    result = malloc(sizeof(struct item));
    if (result == 0) {abort_crypto_lib("Malloc failed");}
    result->size = (int) olen;
    if ((int) olen <= MINIMAL_STRING_SIZE)
      abort_crypto_lib("Decryption: Incorrect size");
    result->content = malloc(result->size);
    if (result->content == 0) {abort_crypto_lib("Malloc failed");}
    //@ close [f]world(pub, key_clsfy);
    //@ assert u_integer(&olen, ?olen_val);
    //@ assert crypto_chars(_, output, olen_val, cs_out);
    //@ crypto_chars_split(output, TAG_LENGTH);
    //@ assert crypto_chars(_, output, TAG_LENGTH, ?cs_tag);
    //@ assert crypto_chars(_, (void*) output + TAG_LENGTH, olen_val - TAG_LENGTH, ?cs_i);
    /*@ if (col)
        {
          crypto_chars_to_chars(output, TAG_LENGTH);
          chars_to_crypto_chars(output, TAG_LENGTH);
        }
        else if (!garbage)
        {
          switch(pay)
          {
            case some(pay1):
              open [_]item_constraints(pay1, cs_out, pub);
            case none:
              open [_]ill_formed_item_chars(enc)(cs_out);
              public_generated_split(polarssl_pub(pub), cs_out, TAG_LENGTH);
          }
          public_crypto_chars(output, TAG_LENGTH);
        }
    @*/
    //@ close check_tag2_ghost_args(false, garbage, p_key, c_key, cs_i);
    check_tag2(output, tag);
    //@ if (!garbage) chars_to_secret_crypto_chars(output, TAG_LENGTH);
    //@ crypto_chars_join(output);
    memcpy(result->content, output, olen);
    //@ assert result->content |-> ?cont;
    //@ assert crypto_chars(?kind, cont, olen_val, cs_out);
    zeroize(output, (int) olen);
    //@ close item(item, enc, pub);
    //@ assert enc == asymmetric_encrypted_item(principal2, count2, pay, ent);
    //@ assert col || enc_cg == cg_asym_encrypted(principal2, count2, cs_pay, ent);
    
    /*@ if (col)
        {
          crypto_chars_to_chars(cont, olen_val);
          public_chars(cont, olen_val);
          chars_to_crypto_chars(cont, olen_val);
        }
        else if (garbage)
        {
          assert true == key_clsfy(principal3, count3, false);
          public_chars(cont, olen_val);
          chars_to_crypto_chars(cont, olen_val);
        }
        else
        {
          assert principal2 == principal3;
          assert count2 == count3;
          assert cs_out == cs_pay;
          switch(pay)
          {
            case some(pay1):
              assert [_]item_constraints(pay1, cs_out, pub);
            case none:
              open [_]ill_formed_item_chars(enc)(cs_out);
              assert [_]public_generated(polarssl_pub(pub))(cs_out);
              public_crypto_chars(cont, olen_val);
              chars_to_crypto_chars(cont, olen_val);
          }
        }
    @*/
    parse_item(result->content, (int) olen);
    /*@ if (col || garbage)
        {
          retreive_proof_obligations();
          deserialize_item(cs_out, pub);
          leak proof_obligations(pub);
          chars_to_secret_crypto_chars(cont, olen_val);
        }
    @*/
    //@ open [_]item_constraints(?dec, cs_out, pub);
    //@ assert [_]ic_parts(dec)(?dec_tag, ?dec_cont);
    //@ take_append(TAG_LENGTH, dec_tag, dec_cont);
    //@ drop_append(TAG_LENGTH, dec_tag, dec_cont);
    //@ assert dec_tag == full_tag(tag);
    //@ assert tag_for_item(dec) == tag;
    //@ close item(result, dec, pub);
  }
  return result;
}
Beispiel #16
0
void parse_pair_item(char* message, int size)
  /*@ requires FORALLP_C &*& FORALLP_CS &*&
               [?f1]world(?pub, ?key_clsfy) &*& exists(?ccs_tag) &*&
               ccs_tag == full_ctag(c_to_cc(TAG_PAIR)) &*&
               TAG_LENGTH == length(ccs_tag) &*&
               size <= INT_MAX - TAG_LENGTH &*& head(ccs_tag) == c_to_cc(TAG_PAIR) &*&
               [?f2]crypto_chars(?kind, message, size, ?ccs_cont) &*&
               switch(kind)
               {
                 case normal:
                   return true;
                 case secret:
                   return [_]item_constraints(pair_item(_, _),
                                              append(ccs_tag, ccs_cont), pub);
               }; @*/
  /*@ ensures  [f1]world(pub, key_clsfy) &*&
               [f2]crypto_chars(kind, message, size, ccs_cont) &*&
               true == well_formed_ccs(forallc, forallcs,
                                   nat_length(append(ccs_tag, ccs_cont)),
                                   append(ccs_tag, ccs_cont)); @*/
{
  //@ open [f1]world(pub, key_clsfy);
  //@ close [f1]world(pub, key_clsfy);
  if (size <= (int) sizeof(int))
    abort_crypto_lib("Incorrect size for pair item");
  //@ list<crypto_char> ccs = append(ccs_tag, ccs_cont);
  //@ take_append(TAG_LENGTH, ccs_tag, ccs_cont);
  //@ drop_append(TAG_LENGTH, ccs_tag, ccs_cont);
  //@ crypto_chars_limits(message);
  //@ crypto_chars_split(message, sizeof(int));
  //@ assert [f2]crypto_chars(kind, message, sizeof(int), ?size_f_ccs);
  /*@ assert [f2]crypto_chars(kind, message + sizeof(int),
                              size - sizeof(int), ?ccs_p); @*/
  //@ take_append(sizeof(int), size_f_ccs, ccs_p);
  //@ drop_append(sizeof(int), size_f_ccs, ccs_p);
  //@ assert ccs_cont == append(size_f_ccs, ccs_p);
  /*@ if (kind == secret)
      {
        assert [_]item_constraints(?p, ccs, pub);
        OPEN_ITEM_CONSTRAINTS(p, ccs, pub);
        public_crypto_chars(message, sizeof(int));
      }
      else
      {
        crypto_chars_to_chars(message, sizeof(int));
      }
  @*/
  //@ assert [f2]chars(message, sizeof(int), ?size_f_cs);
  //@ assert cs_to_ccs(size_f_cs) == size_f_ccs;
  //@ chars_to_integer(message);
  int size_f = *((int*) ((void*) message));
  //@ assert size_f == int_of_chars(size_f_cs);
  //@ integer_to_chars(message);
  if (size_f < MINIMAL_STRING_SIZE || size_f > size - (int) sizeof(int))
    abort_crypto_lib("Incorrect size for pair item");
  int size_s = size - (int) sizeof(int) - size_f;
  //@ crypto_chars_limits(message + sizeof(int));
  //@ crypto_chars_split(message + sizeof(int), size_f);
  /*@ assert [f2]crypto_chars(kind, message + (int) sizeof(int),
                              size_f, ?ccs_f); @*/
  /*@ assert [f2]crypto_chars(kind, message + (int) sizeof(int) + size_f,
                              size_s, ?ccs_s); @*/
  //@ take_append(size_f, ccs_f, ccs_s);
  //@ drop_append(size_f, ccs_f, ccs_s);
  //@ assert ccs_p == append(ccs_f, ccs_s);
  if (size_f <= TAG_LENGTH || size_s <= TAG_LENGTH)
    abort_crypto_lib("Incorrect size for pair item");
  /*@ assert ccs_cont == append(cs_to_ccs(chars_of_unbounded_int(length(ccs_f))),
                                append(ccs_f, ccs_s)); @*/
  /*@ if (kind == secret)
      {
        assert [_]item_constraints(?p, ccs, pub);
        OPEN_ITEM_CONSTRAINTS(p, ccs, pub);
        assert [_]ic_pair(p)(?ccs_f0, ?ccs_s0);
        assert [_]item_constraints(_, ccs_f0, pub);
        assert [_]item_constraints(_, ccs_s0, pub);
        cs_to_ccs_inj(chars_of_int(length(ccs_f)),
                      chars_of_int(length(ccs_f0)));
        take_append(size_f, ccs_f0, ccs_s0);
        drop_append(size_f, ccs_f0, ccs_s0);
      }
  @*/
  parse_item(message + (int) sizeof(int), size_f);
  parse_item(message + (int) sizeof(int) + size_f, size_s);

  //@ crypto_chars_join(message + sizeof(int));
  //@ if (kind == normal) chars_to_crypto_chars(message, sizeof(int));
  //@ if (kind == secret) chars_to_secret_crypto_chars(message, sizeof(int));
  //@ crypto_chars_join(message);

  //@ length_equals_nat_length(ccs);
  //@ length_equals_nat_length(ccs_cont);
  /*@ switch(nat_length(ccs))
      {
        case succ(n):
          well_formed_upper_bound(nat_length(ccs_f), nat_length(ccs_cont), ccs_f);
          well_formed_upper_bound(nat_length(ccs_s), nat_length(ccs_cont), ccs_s);
          assert length(ccs) > 0;
          assert length(ccs) <= INT_MAX;
          assert true == well_formed_ccs(forallc, forallcs, nat_length(ccs_f), ccs_f);
          assert true == well_formed_ccs(forallc, forallcs, nat_length(ccs_s), ccs_s);
          head_append(ccs_tag, ccs_cont);
          well_formed_pair_item(ccs, size_f, ccs_f, ccs_s);
        case zero:
          assert false;
      }
  @*/
}
struct item *symmetric_encryption(struct item *key, struct item *payload)
  /*@ requires [?f]world(?pub, ?key_clsfy) &*&
               principal(?principal1, ?count1) &*&
                 [_]pub(nonce_item(principal1, count1 + 1, 0)) &*&
               item(payload, ?pay, pub) &*& item(key, ?k, pub) &*&
                 k == symmetric_key_item(?principal2, ?count2); @*/
  /*@ ensures  [f]world(pub, key_clsfy) &*&
               principal(principal1, count1 + 2) &*&
               item(payload, pay, pub) &*& item(key, k, pub) &*&
               item(result, ?enc, pub) &*&
               col ? true :
                 enc == symmetric_encrypted_item(principal2, count2,
                                                 some(pay), ?ent); @*/
{
  //@ open [f]world(pub, key_clsfy);
  debug_print("ENCRYPTING:\n");
  print_item(payload);

  struct item* result;
  result = malloc(sizeof(struct item));
  if (result == 0) abort_crypto_lib("Malloc failed");

  {
    gcm_context gcm_context;
    char iv_buffer[GCM_IV_SIZE];
    char *iv;
    char *result_cs;
    char *encrypted;

    //@ open item(key, k, pub);
    //@ assert key->content |-> ?k_cont &*& key->size |-> ?k_size;
    check_valid_symmetric_key_item_size(key->size);
    //@ open [_]item_constraints(k, ?k_cs0, pub);
    //@ assert [_]ic_parts(k)(?k_tag, ?k_cs);
    //@ crypto_chars_limits(k_cont);
    //@ crypto_chars_split(k_cont, TAG_LENGTH);
    //@ WELL_FORMED(k_tag, k_cs, TAG_SYMMETRIC_KEY)
    //@ assert crypto_chars(secret, k_cont, TAG_LENGTH, k_tag);
    //@ assert crypto_chars(secret, k_cont + TAG_LENGTH, GCM_KEY_SIZE, k_cs);
    //@ cryptogram k_cg = cg_symmetric_key(principal2, count2);
    //@ if (col) k_cg = chars_for_cg_sur(k_cs, tag_symmetric_key);
    //@ if (col) crypto_chars_to_chars(k_cont + TAG_LENGTH, GCM_KEY_SIZE);
    //@ if (col) public_chars_extract(k_cont + TAG_LENGTH, k_cg);
    //@ if (col) chars_to_secret_crypto_chars(k_cont + TAG_LENGTH, GCM_KEY_SIZE);
    //@ close cryptogram(k_cont + TAG_LENGTH, GCM_KEY_SIZE, k_cs, k_cg);
    //@ close gcm_context(&gcm_context);
    if (gcm_init(&gcm_context, POLARSSL_CIPHER_ID_AES, (key->content + TAG_LENGTH),
                (unsigned int) GCM_KEY_SIZE * 8) != 0)
      abort_crypto_lib("Init gcm failed");
    //@ assert gcm_context_initialized(&gcm_context, ?p, ?c);
    //@ assert col || (p == principal2 && c == count2);
    //@ open cryptogram(k_cont + TAG_LENGTH, GCM_KEY_SIZE, k_cs, k_cg);
    //@ crypto_chars_join(k_cont);
    //@ close item(key, k, pub);

    //@ open item(payload, pay, pub);
    //@ open [_]item_constraints(pay, ?pay_cs, pub);
    //@ assert payload->content |-> ?p_cont &*& payload->size |-> ?p_size;
    //@ crypto_chars_limits(p_cont);
    if (payload->size >= INT_MAX - TAG_LENGTH - GCM_IV_SIZE - GCM_MAC_SIZE ||
        payload->size < MINIMAL_STRING_SIZE)
      abort_crypto_lib("Gcm encryption failed: incorrect sizes");
    result->size = TAG_LENGTH + GCM_IV_SIZE + GCM_MAC_SIZE + payload->size;
    result->content = malloc(result->size);

    //@ assert result->content |-> ?r_cont &*& result->size |-> ?r_size;
    if (result->content == 0)
      abort_crypto_lib("Malloc failed");
    //@ chars_split(r_cont, TAG_LENGTH);
    write_tag(result->content, TAG_SYMMETRIC_ENC);
    //@ assert chars(r_cont, TAG_LENGTH, ?tag_cs);
    //@ public_chars(r_cont, TAG_LENGTH);
    //@ assert tag_cs == full_tag(TAG_SYMMETRIC_ENC);
    //@ assert chars(r_cont + TAG_LENGTH, GCM_IV_SIZE + p_size, _);
    //@ chars_split(r_cont + TAG_LENGTH, GCM_IV_SIZE);
    iv = result->content + TAG_LENGTH;
    //@ close nonce_request(principal1, 0);
    //@ close [f]world(pub, key_clsfy);
    create_havege_random(iv, GCM_IV_SIZE);
    //@ open cryptogram(iv, GCM_IV_SIZE, ?iv_cs, ?iv_cg);
    memcpy(iv_buffer, iv, GCM_IV_SIZE);
    //@ close cryptogram(iv, GCM_IV_SIZE, iv_cs, iv_cg);
    //@ close polarssl_pub(pub)(iv_cg);
    //@ leak polarssl_pub(pub)(iv_cg);
    //@ public_cryptogram(iv, iv_cg);
    //@ public_chars(iv, GCM_IV_SIZE);
    encrypted = iv + GCM_IV_SIZE;
    //@ chars_split(encrypted, GCM_MAC_SIZE);
    //@ open principal(principal1, count1 + 1);
    if (gcm_crypt_and_tag(&gcm_context, GCM_ENCRYPT,
                          (unsigned int) payload->size, iv_buffer, 
                          GCM_IV_SIZE, NULL, 0, payload->content, 
                          encrypted + GCM_MAC_SIZE,
                          GCM_MAC_SIZE, encrypted) != 0)
      abort_crypto_lib("Gcm encryption failed");
    //@ close principal(principal1, count1 + 2);
    zeroize(iv_buffer, GCM_IV_SIZE);
    //@ assert crypto_chars(secret, encrypted, GCM_MAC_SIZE, ?mac_cs);
    //@ assert crypto_chars(secret, encrypted + GCM_MAC_SIZE, p_size, ?enc_cs);
    //@ crypto_chars_join(encrypted);
    //@ assert exists(?enc_cg);
    //@ list<char> cg_cs = append(mac_cs, enc_cs);
    //@ assert cg_cs == chars_for_cg(enc_cg);
    //@ list<char> cont_cs = append(iv_cs, cg_cs);
    //@ take_append(GCM_IV_SIZE, iv_cs, cg_cs);
    //@ drop_append(GCM_IV_SIZE, iv_cs, cg_cs);
    //@ list<char> cs = append(tag_cs, cont_cs);
    //@ take_append(TAG_LENGTH, tag_cs, cont_cs);
    //@ drop_append(TAG_LENGTH, tag_cs, cont_cs);
    
    //@ item enc;
    //@ list<char> ent = append(iv_cs, iv_cs);
    //@ take_append(GCM_IV_SIZE, iv_cs, iv_cs);
    //@ drop_append(GCM_IV_SIZE, iv_cs, iv_cs);
    /*@ if (col)
        {
          enc_cg = chars_for_cg_sur(cg_cs, tag_auth_encrypted);
          assert enc_cg == cg_auth_encrypted(?p0, ?c0, ?pay0, ?iv0);
          ent = append(iv_cs, iv0);
          take_append(GCM_IV_SIZE, iv_cs, iv0);
          drop_append(GCM_IV_SIZE, iv_cs, iv0);
          enc = symmetric_encrypted_item(p0, c0, some(pay), ent);
          public_chars(encrypted, GCM_MAC_SIZE + p_size);
          assert chars(encrypted, GCM_MAC_SIZE + p_size, cg_cs);
          chars_join(iv);
          chars_join(r_cont);
          assert chars(r_cont, r_size, cs);
          public_chars(r_cont, r_size);
          public_generated_split(polarssl_pub(pub), cs, TAG_LENGTH);
          close ic_sym_enc(enc)(iv0, cg_cs);
        }
        else
        {
          assert enc_cg == cg_auth_encrypted(principal2, count2, pay_cs, iv_cs);
          enc = symmetric_encrypted_item(principal2, count2, some(pay), ent);
          close polarssl_pub(pub)(cg_nonce(principal1, count1 + 1));
          leak  polarssl_pub(pub)(cg_nonce(principal1, count1 + 1));
          public_generated(polarssl_pub(pub), cg_nonce(principal1, count1 + 1));
          chars_to_secret_crypto_chars(iv, GCM_IV_SIZE);
          crypto_chars_join(iv);
          chars_to_secret_crypto_chars(r_cont, TAG_LENGTH);
          crypto_chars_join(r_cont);
          assert crypto_chars(secret, r_cont, r_size, cs);
          close ic_sym_enc(enc)(iv_cs, cg_cs);
        }
    @*/
    //@ well_formed_item_constraints(pay, enc);
    //@ close ic_cg(enc)(cg_cs, enc_cg);
    //@ close ic_parts(enc)(tag_cs, cont_cs);
    //@ WELL_FORMED(tag_cs, cont_cs, TAG_SYMMETRIC_ENC)
    //@ close item_constraints(enc, cs, pub);
    //@ leak item_constraints(enc, cs, pub);
    //@ close item(result, enc, pub);
    //@ close item(payload, pay, pub);
    gcm_free(&gcm_context);
    //@ open gcm_context(&gcm_context);
  }

  debug_print("ENCRYPTING RESULT:\n");
  print_item(result);

  return result;
}
struct item *symmetric_decryption(struct item *key, struct item *item)
  /*@ requires [?f]world(?pub, ?key_clsfy) &*&
               item(item, ?enc, pub) &*&
                 enc == symmetric_encrypted_item(?principal1, ?count1,
                                                 ?pay, ?ent) &*&
               item(key, ?k, pub) &*&
                 k == symmetric_key_item(?principal2, ?count2); @*/
  /*@ ensures  [f]world(pub, key_clsfy) &*&
               item(item, enc, pub) &*& item(key, k, pub) &*&
               item(result, ?dec, pub) &*&
               col ? [_]pub(dec) :
               switch(pay)
               {
                 case some(dec2):
                   return principal1 == principal2 &&
                          count1 == count2 && dec == dec2;
                 case none:
                   return false;
               }; @*/
{
  debug_print("DECRYPTING:\n");
  print_item(item);
  check_is_symmetric_encrypted(item);

  //@ open [f]world(pub, key_clsfy);
  struct item* result;
  result = malloc(sizeof(struct item));
  if (result == 0) abort_crypto_lib("Malloc failed");

  {
    gcm_context gcm_context;
    char *iv;
    char iv_buffer[GCM_IV_SIZE];
    char *encrypted;

    //@ open item(key, k, pub);
    //@ assert key->content |-> ?k_cont &*& key->size |-> ?k_size;
    check_valid_symmetric_key_item_size(key->size);
    //@ open [_]item_constraints(k, ?k_cs0, pub);
    //@ assert [_]ic_parts(k)(?k_tag, ?k_cs);
    //@ crypto_chars_limits(k_cont);
    //@ crypto_chars_split(k_cont, TAG_LENGTH);
    //@ WELL_FORMED(k_tag, k_cs, TAG_SYMMETRIC_KEY)
    //@ assert crypto_chars(secret, k_cont, TAG_LENGTH, k_tag);
    //@ assert crypto_chars(secret, k_cont + TAG_LENGTH, GCM_KEY_SIZE, k_cs);
    //@ cryptogram k_cg = cg_symmetric_key(principal2, count2);
    //@ if (col) k_cg = chars_for_cg_sur(k_cs, tag_symmetric_key);
    //@ if (col) crypto_chars_to_chars(k_cont + TAG_LENGTH, GCM_KEY_SIZE);
    //@ if (col) public_chars_extract(k_cont + TAG_LENGTH, k_cg);
    //@ if (col) chars_to_secret_crypto_chars(k_cont + TAG_LENGTH, GCM_KEY_SIZE);
    //@ close cryptogram(k_cont + TAG_LENGTH, GCM_KEY_SIZE, k_cs, k_cg);
    //@ close gcm_context(&gcm_context);
    if (gcm_init(&gcm_context, POLARSSL_CIPHER_ID_AES, (key->content + TAG_LENGTH),
                (unsigned int) GCM_KEY_SIZE * 8) != 0)
      abort_crypto_lib("Init gcm failed");
    //@ assert gcm_context_initialized(&gcm_context, ?p, ?c);
    //@ assert col || (p == principal2 && c == count2);
    //@ open cryptogram(k_cont + TAG_LENGTH, GCM_KEY_SIZE, k_cs, k_cg);
    //@ crypto_chars_join(k_cont);
    //@ close item(key, k, pub);

    //@ open item(item, enc, pub);
    //@ assert item->content |-> ?i_cont &*& item->size |-> ?i_size;
    //@ open [_]item_constraints(enc, ?cs, pub);
    //@ open [_]ic_parts(enc)(?enc_tag, ?enc_cont);
    //@ open [_]ic_cg(enc)(_, ?enc_cg);
    //@ take_append(TAG_LENGTH, enc_tag, enc_cont);
    //@ drop_append(TAG_LENGTH, enc_tag, enc_cont);
    //@ open [_]ic_sym_enc(enc)(?enc_iv, ?cg_cs);
    //@ assert true == well_formed(cs, nat_length(cs));
    //@ close [1/2]hide_crypto_chars(_, i_cont, i_size, cs);
    check_valid_symmetric_encrypted_item_size(item->size);
    //@ assert length(cs) > TAG_LENGTH + GCM_IV_SIZE;
    int size = item->size - TAG_LENGTH - GCM_IV_SIZE - GCM_MAC_SIZE;
    if (size <= MINIMAL_STRING_SIZE) abort_crypto_lib("Gcm decryption failed");
    //@ crypto_chars_limits(i_cont);
    //@ crypto_chars_split(i_cont, TAG_LENGTH);
    iv = item->content + TAG_LENGTH;
    //@ crypto_chars_split(iv, GCM_IV_SIZE);
    //@ assert [1/2]crypto_chars(secret, iv, GCM_IV_SIZE, ?iv_cs);
    memcpy(iv_buffer, iv, GCM_IV_SIZE);
    //@ assert cs == append(enc_tag, enc_cont);
    //@ assert enc_cont == append(iv_cs, cg_cs);
    //@ public_crypto_chars(iv, GCM_IV_SIZE);
    //@ chars_to_secret_crypto_chars(iv, GCM_IV_SIZE);
    encrypted = iv + GCM_IV_SIZE;
    //@ crypto_chars_limits(encrypted);
    //@ crypto_chars_split(encrypted, GCM_MAC_SIZE);
    //@ assert [1/2]crypto_chars(secret, encrypted, GCM_MAC_SIZE, ?mac_cs);
    /*@ assert [1/2]crypto_chars(secret, encrypted + GCM_MAC_SIZE, 
                                 size, ?enc_cs); @*/
    //@ assert cg_cs == append(mac_cs, enc_cs);                             
    result->size = size;
    result->content = malloc(size);
    if (result->content == 0) abort_crypto_lib("Malloc failed");
    //@ assert result->content |-> ?r_cont &*& result->size |-> size;
    //@ if (col) enc_cg = chars_for_cg_sur(cg_cs, tag_auth_encrypted);
    //@ close exists(enc_cg);
    if (gcm_auth_decrypt(&gcm_context, (unsigned int) size,
                         iv_buffer, GCM_IV_SIZE, NULL, 0, encrypted, 
                         GCM_MAC_SIZE, encrypted + GCM_MAC_SIZE,
                         result->content) != 0)
      abort_crypto_lib("Gcm decryption failed");
    //@ assert crypto_chars(secret, r_cont, size, ?dec_cs);
    //@ assert col || enc_cg == cg_auth_encrypted(principal1, count1, dec_cs, iv_cs);
    //@ crypto_chars_join(encrypted);
    //@ crypto_chars_join(iv);
    //@ crypto_chars_join(i_cont);
    //@ open [1/2]hide_crypto_chars(_, i_cont, i_size, cs);
    //@ close item(item, enc, pub);
    gcm_free(&gcm_context);
    //@ open gcm_context(&gcm_context);
    zeroize(iv_buffer, GCM_IV_SIZE);
    //@ close [f]world(pub, key_clsfy);
    
    /*@ if (col)
        {
          crypto_chars_to_chars(r_cont, size);
          chars_to_crypto_chars(r_cont, size);
        }
        else
        {
          assert enc == symmetric_encrypted_item(principal1, count1,
                                                 pay, ent);
          assert enc_cg == cg_auth_encrypted(principal1, count1, 
                                             dec_cs, enc_iv);
          switch(pay)
          {
            case some(pay1):
              assert [_]item_constraints(pay1, dec_cs, pub);
            case none:
              open [_]ill_formed_item_chars(enc)(dec_cs);
              assert [_]public_generated(polarssl_pub(pub))(dec_cs);
              public_crypto_chars(r_cont, size);
              chars_to_crypto_chars(r_cont, size);
          }
        }
    @*/
    parse_item(result->content, size);
    /*@ if (col)
        {
          public_chars(r_cont, size);
          chars_to_secret_crypto_chars(r_cont, size);
          retreive_proof_obligations();
          deserialize_item(dec_cs, pub);
          leak proof_obligations(pub);
        }
    @*/
    //@ assert crypto_chars(secret, r_cont, size, dec_cs);
    //@ assert [_]item_constraints(?r, dec_cs, pub);
    //@ close item(result, r, pub);
  }

  debug_print("DECRYPTING RESULT:\n");
  print_item(result);

  return result;
}
Beispiel #19
0
void parse_item(char* buffer, int size)
  /*@ requires FORALLP_C &*& FORALLP_CS &*&
               [?f1]world(?pub, ?key_clsfy) &*&
               [?f2]crypto_chars(?kind, buffer, size, ?ccs) &*&
               size > TAG_LENGTH &*&
               kind == normal ? true :
                 [_]item_constraints(?i, ccs, pub); @*/
  /*@ ensures  [f1]world(pub, key_clsfy) &*&
               [f2]crypto_chars(kind, buffer, size, ccs) &*&
               true == well_formed_ccs(forallc, forallcs, nat_length(ccs), ccs); @*/
{
  //@ open [f1]world(pub, key_clsfy);
  //@ close [f1]world(pub, key_clsfy);
  //@ crypto_chars_limits(buffer);
  //@ crypto_chars_split(buffer, TAG_LENGTH);
  //@ assert [f2]crypto_chars(kind, buffer, TAG_LENGTH, ?ccs_tag);
  /*@ assert [f2]crypto_chars(kind, buffer + TAG_LENGTH,
                              size - TAG_LENGTH,  ?cs_cont); @*/
  /*@ switch (kind)
      {
        case normal:
          crypto_chars_to_chars(buffer, TAG_LENGTH);
        case secret:
          assert [_]item_constraints(?i, ccs, pub);
          OPEN_ITEM_CONSTRAINTS(i, ccs, pub);
          public_crypto_chars(buffer, TAG_LENGTH);
      }
  @*/
  //@ open [f2]chars(buffer, TAG_LENGTH, ?cs_tag);
  //@ assert ccs_tag == cs_to_ccs(cs_tag);
  char t = *(buffer);
  //@ close [f2]chars(buffer, TAG_LENGTH, cs_tag);
  check_tag(buffer, t);
  //@ cs_to_ccs_full_tag(t);
  //@ assert cs_tag == full_tag(t);
  //@ length_equals_nat_length(ccs);
  //@ SWITCH_TAG(t)
  switch (t)
  {
    case TAG_DATA:
      break;
    case TAG_PAIR:
      //@ close exists(ccs_tag);
      parse_pair_item(buffer + TAG_LENGTH, size - TAG_LENGTH);
      break;
    case TAG_NONCE:
      if (size != TAG_LENGTH + 1 + NONCE_SIZE)
        abort_crypto_lib("Could not parse nonce: illegal size");
      break;
    case TAG_HASH:
      if (size != TAG_LENGTH + HASH_SIZE)
        abort_crypto_lib("Could not parse hash: illegal size");
      break;
    case TAG_SYMMETRIC_KEY:
      if (size != TAG_LENGTH + GCM_KEY_SIZE)
        abort_crypto_lib("Could not parse symmetric key: illegal size");
      break;
    case TAG_PUBLIC_KEY:
      if (size != TAG_LENGTH + RSA_SERIALIZED_KEY_SIZE)
        abort_crypto_lib("Could not parse public key: illegal size");
      break;
    case TAG_PRIVATE_KEY:
      if (size != TAG_LENGTH + RSA_SERIALIZED_KEY_SIZE)
        abort_crypto_lib("Could not parse private key: illegal size");
      break;
    case TAG_HMAC:
      if (size != TAG_LENGTH + HMAC_SIZE)
        abort_crypto_lib("Could not parse private key: illegal size");
      break;
    case TAG_SYMMETRIC_ENC:
      if (size < TAG_LENGTH + GCM_IV_SIZE + MINIMAL_STRING_SIZE)
        abort_crypto_lib("Could not parse symmetric encrypted item: illegal size");
      break;
    case TAG_ASYMMETRIC_ENC:
      if (size > TAG_LENGTH + RSA_SERIALIZED_KEY_SIZE ||
          size < TAG_LENGTH + MINIMAL_STRING_SIZE)
        abort_crypto_lib("Could not parse asymmetric encrypted item: illegal size");
      break;
    case TAG_ASYMMETRIC_SIG:
      if (size > TAG_LENGTH + RSA_SERIALIZED_KEY_SIZE ||
          size < TAG_LENGTH + MINIMAL_STRING_SIZE)
        abort_crypto_lib("Could not parse asymmetric signature item: illegal size");
      break;
    default:
      abort_crypto_lib("Found illegal tag during deserialization");
  }
  /*@ if (!exists_t<char>(forallc, (valid_ctag)(head(ccs))))
      {
        forall_t_elim(forallc, (notf)((valid_ctag)(head(ccs))), t);
        assert false;
      }
  @*/
  //@ assert true == well_formed_ccs(forallc, forallcs, nat_length(ccs), ccs);
  //@ if (kind == normal) chars_to_crypto_chars(buffer, TAG_LENGTH);
  //@ if (kind == secret) chars_to_secret_crypto_chars(buffer, TAG_LENGTH);
  //@ crypto_chars_join(buffer);
}
struct item *asymmetric_signature(struct item *key, struct item *payload)
  /*@ requires [?f]world(?pub, ?key_clsfy) &*&
               principal(?principal1, ?count1) &*&
               item(payload, ?pay, pub) &*& item(key, ?k, pub) &*&
               k == private_key_item(?principal2, ?count2); @*/
  /*@ ensures  [f]world(pub, key_clsfy) &*&
               principal(principal1, count1 + 1) &*&
               item(payload, pay, pub) &*& item(key, k, pub) &*&
               item(result, ?sig, pub) &*&
               col ? true :
                 sig == asymmetric_signature_item(principal2, count2,
                                                  some(pay), ?ent); @*/
{
  debug_print("ASYM SIGNING:\n");
  print_item(payload);

  struct item* result;
  result = malloc(sizeof(struct item));
  if (result == 0) abort_crypto_lib("Malloc failed");

  debug_print("signing item\n");
  print_item(payload);
  print_item(key);

  {
    pk_context context;
    unsigned int olen;
    char* output;

    // Key
    //@ close pk_context(&context);
    //@ open [f]world(pub, key_clsfy);
    pk_init(&context);
    //@ close [f]world(pub, key_clsfy);
    set_private_key(&context, key);
    //@ open [f]world(pub, key_clsfy);
    /*@ assert pk_context_with_key(&context, pk_private,
                                   ?principal, ?count, RSA_BIT_KEY_SIZE); @*/
    //@ assert col || principal == principal2;
    //@ assert col || count == count2;

    // Payload
    //@ open item(payload, pay, pub);
    //@ open [_]item_constraints(pay, ?pay_cs, pub);
    //@ assert payload->content |-> ?p_cont &*& payload->size |-> ?p_size;
    if (payload->size > RSA_KEY_SIZE)
      abort_crypto_lib("Assymetric signing failed: incorrect size");
    output = malloc(RSA_KEY_SIZE);
    if (output == 0) abort_crypto_lib("Malloc failed");

    void *random_state = nonces_expose_state();
    //@ close random_state_predicate(havege_state_initialized);
    /*@ produce_function_pointer_chunk random_function(
                      asym_sig_havege_random_stub)
                     (havege_state_initialized)(state, out, len) { call(); } @*/
    //@ open principal(principal1, count1);
    if(pk_sign(&context, POLARSSL_MD_NONE,
               payload->content, (unsigned int) payload->size,
               output, &olen,
               asym_sig_havege_random_stub, random_state) != 0)
      abort_crypto_lib("Signing failed");
    //@ open principal(principal1, count1 + 1);
    //@ open cryptogram(output, ?sig_length, ?sig_cs, ?sig_cg);
    //@ assert sig_cg == cg_asym_signature(principal, count, pay_cs, ?ent);
    //@ assert u_integer(&olen, sig_length);
    //@ assert sig_length > 0 &*& sig_length <= RSA_KEY_SIZE;
    nonces_hide_state(random_state);
    //@ pk_release_context_with_key(&context);
    pk_free(&context);
    //@ open pk_context(&context);
    //@ close [f]world(pub, key_clsfy);
    debug_print("signed item\n");
    print_buffer(output, (int) olen);

    // Create item
    if (olen < MINIMAL_STRING_SIZE)
      abort_crypto_lib("Assymetric signing failed: output to small");
    result->size = TAG_LENGTH + (int) olen;
    result->content = malloc(result->size);
    if (result->content == 0) {abort_crypto_lib("Malloc failed");}
    write_tag(result->content, TAG_ASYMMETRIC_SIG);
    //@ assert result->content |-> ?cont &*& result->size |-> ?size;
    //@ assert chars(cont, TAG_LENGTH, ?tag_cs);
    //@ assert tag_cs == full_tag(TAG_ASYMMETRIC_SIG);
    //@ public_chars(cont, TAG_LENGTH);
    //@ chars_to_secret_crypto_chars(cont, TAG_LENGTH);
    memcpy(result->content + TAG_LENGTH, output, olen);

    //@ crypto_chars_join(cont);
    //@ list<char> cs = append(tag_cs, sig_cs);
    //@ assert crypto_chars(secret, cont, size, cs);

    //@ item e = asymmetric_signature_item(principal, count, some(pay), ent);
    //@ close ic_cg(e)(sig_cs, sig_cg);
    /*@ if (col)
        {
          public_chars(cont, size);
          public_generated_split(polarssl_pub(pub), cs, TAG_LENGTH);
        }
    @*/
    //@ close item(payload, pay, pub);
    zeroize(output, (int) olen);
    //@ chars_join(output);
    free(output);
    //@ WELL_FORMED(tag_cs, sig_cs, TAG_ASYMMETRIC_SIG)
    //@ close ic_parts(e)(tag_cs, sig_cs);
    //@ close well_formed_item_chars(e)(pay_cs);
    //@ leak well_formed_item_chars(e)(pay_cs);
    //@ close item_constraints(e, cs, pub);
    //@ leak item_constraints(e, cs, pub);
    //@ close item(result, e, pub);
  }
  debug_print("SINGING RESULT:\n");
  print_item(result);

  return result;
}
Beispiel #21
0
struct item *create_pair(struct item *first, struct item *second)
  /*@ requires [?f0]world(?pub, ?key_clsfy) &*&
               [?f1]item(first, ?f, pub) &*& [?f2]item(second, ?s, pub); @*/
  /*@ ensures  [f0]world(pub, key_clsfy) &*&
               [f1]item(first, f, pub) &*& [f2]item(second, s, pub) &*&
               item(result, pair_item(f, s), pub); @*/
{
  //@ open [f0]world(pub, key_clsfy);
  struct item* pair = malloc(sizeof(struct item));
  if (pair == 0){abort_crypto_lib("malloc of item failed");}

  //@ open [f1]item(first, f, pub);
  //@ assert [f1]first->content |-> ?cont_f &*& [f1]first->size |-> ?size_f;
  //@ assert [f1]crypto_chars(secret, cont_f, size_f, ?cs_f);
  //@ assert [_]item_constraints(f, cs_f, pub);
  //@ well_formed_item_constraints(f, f);
  //@ open [_]well_formed_item_chars(f)(cs_f);
  //@ open [f2]item(second, s, pub);
  //@ assert [f2]second->content |-> ?cont_s &*& [f2]second->size |-> ?size_s;
  //@ assert [f2]crypto_chars(secret, cont_s, size_s, ?cs_s);
  //@ well_formed_item_constraints(s, s);
  //@ open [_]well_formed_item_chars(s)(cs_s);
  //@ assert [_]item_constraints(s, cs_s, pub);
  if (INT_MAX - TAG_LENGTH - (int) sizeof(int) - first->size < second->size)
    abort_crypto_lib("Requested pair item was to big");
  pair->size = TAG_LENGTH + (int) sizeof(int) + first->size + second->size;
  pair->content = malloc_wrapper(pair->size);
  //@ assert pair->content |-> ?cont &*& pair->size |-> ?size;
  write_tag(pair->content, TAG_PAIR);
  {
    //@ assert chars(cont, TAG_LENGTH, full_tag(TAG_PAIR));
    //@ public_chars(cont, TAG_LENGTH);
    //@ chars_to_secret_crypto_chars(cont, TAG_LENGTH);
    char* temp = pair->content + TAG_LENGTH;
    //@ chars_split(cont + TAG_LENGTH, sizeof(int));
    //@ assert [f1]integer(&first->size, ?flen);
    //@ integer_to_chars(&first->size);
    //@ open chars((void*) &first->size, sizeof(int), chars_of_int(flen));
    //@ character_limits((void*) &first->size);
    //@ close [f1]chars((void*) &first->size, sizeof(int), chars_of_int(flen));
    //@ public_chars((void*) &first->size, sizeof(int));
    //@ public_chars((void*) &first->size, sizeof(int));
    //@ chars_to_crypto_chars((void*) &first->size, sizeof(int));
    write_buffer(&temp, (void*) &(first->size), (int) sizeof(int));
    //@ crypto_chars_to_chars((void*) &first->size, sizeof(int));
    //@ chars_to_secret_crypto_chars(temp - sizeof(int), sizeof(int));
    //@ chars_to_integer(&first->size);
    //@ chars_split(cont + TAG_LENGTH + sizeof(int), first->size);
    write_buffer(&temp, first->content, first->size);
    write_buffer(&temp, second->content, second->size);
    //@ crypto_chars_join(cont + TAG_LENGTH + sizeof(int));
    //@ crypto_chars_join(cont + TAG_LENGTH);
    //@ crypto_chars_join(cont);
  }
  //@ list<char> size_f_cs = chars_of_int(size_f);
  //@ list<char> cs0 = append(size_f_cs, append(cs_f, cs_s));
  //@ list<char> cs = append(full_tag(TAG_PAIR), cs0);
  //@ take_append(TAG_LENGTH, full_tag(TAG_PAIR), cs0);
  //@ drop_append(TAG_LENGTH, full_tag(TAG_PAIR), cs0);
  //@ assert length(size_f_cs) == sizeof(int);
  //@ take_append(sizeof(int), size_f_cs, append(cs_f, cs_s));
  //@ drop_append(sizeof(int), size_f_cs, append(cs_f, cs_s));
  //@ take_append(size_f, cs_f, cs_s);
  //@ drop_append(size_f, cs_f, cs_s);
  //@ assert drop(sizeof(int), cs0) == append(cs_f, cs_s);
  //@ assert size_f_cs == chars_of_unbounded_int(length(cs_f));
  //@ append_assoc(size_f_cs, cs_f, cs_s);
  //@ assert crypto_chars(secret, cont, size, cs);
  //@ item p = pair_item(f, s);
  //@ close ic_pair(p)(cs_f, cs_s);
  //@ length_equals_nat_length(cs);
  //@ length_equals_nat_length(cs0);
  //@ drop_drop(sizeof(int), TAG_LENGTH, cs);
  //@ head_append(full_tag(TAG_PAIR), cs0);
  /*@ switch(nat_length(cs))
      {
        case succ(n):
          well_formed_upper_bound(cs_f, nat_length(cs_f), n);
          well_formed_upper_bound(cs_s, nat_length(cs_s), n);
        case zero:
          assert false;
      }
  @*/
  /*@ if(col)
      {
        public_chars(cont, size);
        public_generated_split(polarssl_pub(pub), cs, TAG_LENGTH);
      }
  @*/
  //@ close ic_parts(p)(full_tag(TAG_PAIR), cs0);
  //@ close item_constraints(p, cs, pub);
  //@ leak item_constraints(p, cs, pub);
  //@ close item(pair, p, pub);

  //@ close [f1]item(first, f, pub);
  //@ close [f2]item(second, s, pub);
  return pair;
  //@ close [f0]world(pub, key_clsfy);
}
void asymmetric_signature_verify(struct item *key, struct item *item,
                                 struct item *signature)
  /*@ requires [?f]world(?pub, ?key_clsfy) &*&
               item(item, ?i, pub) &*& item(key, ?k, pub) &*&
               item(signature, ?sig, pub) &*&
                 sig == asymmetric_signature_item(?principal1, ?count1,
                                                  ?pay1, ?ent) &*&
               k == public_key_item(?principal2, ?count2); @*/
  /*@ ensures  [f]world(pub, key_clsfy) &*&
               item(item, i, pub) &*& item(key, k, pub) &*&
               item(signature, sig, pub) &*&
               switch(pay1)
               {
                 case some(pay2):
                   return col || (principal1 == principal2 &&
                                  count1 == count2 && i == pay2);
                 case none:
                   return true == col;
               }; @*/
{
  debug_print("ASYM SIGNATURE CHECKING:\n");
  print_item(signature);
  check_is_asymmetric_signature(signature);

  {
    pk_context context;
    unsigned int olen;
    char* output;

    // Key
    //@ close pk_context(&context);
    //@ open [f]world(pub, key_clsfy);
    pk_init(&context);
    //@ close [f]world(pub, key_clsfy);
    set_public_key(&context, key);
    /*@ assert pk_context_with_key(&context, pk_public,
                                   ?principal3, ?count3, RSA_BIT_KEY_SIZE); @*/
    // Signature checking
    //@ open item(item, ?i_old, pub);
    //@ assert item->content |-> ?i_cont &*& item->size |-> ?i_size;
    //@ assert crypto_chars(secret, i_cont, i_size, ?i_cs);
    //@ assert [_]item_constraints(i, i_cs, pub);
    //@ open item(signature, _, pub);
    //@ assert signature->content |-> ?s_cont &*& signature->size |-> ?s_size;
    //@ assert crypto_chars(secret, s_cont, s_size, ?sig_cs);
    //@ open [_]item_constraints(sig, sig_cs, pub);
    //@ open ic_parts(sig)(?sig_tag, ?sig_cont);
    //@ take_append(TAG_LENGTH, sig_tag, sig_cont);
    //@ drop_append(TAG_LENGTH, sig_tag, sig_cont);
    //@ open [_]ic_cg(sig)(_, ?cg_sig);
    //@ assert cg_sig == cg_asym_signature(principal1, count1, ?cs_pay, ent);

    if (item->size > RSA_KEY_SIZE)
      abort_crypto_lib("Assymetric signature checking failed: incorrect sizes");

    //@ crypto_chars_limits(s_cont);
    //@ crypto_chars_split(s_cont, TAG_LENGTH);
    //@ assert crypto_chars(secret, s_cont, TAG_LENGTH, sig_tag);
    //@ assert crypto_chars(secret, s_cont + TAG_LENGTH, ?s, sig_cont);
    //@ assert s == s_size - TAG_LENGTH;
    //@ if (col) cg_sig = chars_for_cg_sur(sig_cont, tag_asym_signature);
    //@ if (col) crypto_chars_to_chars(s_cont + TAG_LENGTH, s);
    //@ if (col) public_chars_extract(s_cont + TAG_LENGTH, cg_sig);
    //@ if (col) chars_to_secret_crypto_chars(s_cont + TAG_LENGTH, s);
    //@ close cryptogram(s_cont + TAG_LENGTH, s, sig_cont, cg_sig);
    if(pk_verify(&context, POLARSSL_MD_NONE, item->content,
                 (unsigned int) item->size,
                 signature->content + TAG_LENGTH,
                 (unsigned int) (signature->size - TAG_LENGTH)) != 0)
      abort_crypto_lib("Signing check failed: signature"
                       "was not created with the provided key");
    //@ pk_release_context_with_key(&context);
    pk_free(&context);
    //@ open pk_context(&context);
    //@ open cryptogram(s_cont + TAG_LENGTH, s, sig_cont, cg_sig);
    //@ crypto_chars_join(s_cont);
    //@ close item(signature, sig, pub);

    /*@ if (!col)
        {
          assert principal2 == principal3;
          assert count2 == count3;
          assert cs_pay == i_cs;
          open [_]item_constraints(i, cs_pay, pub);
          switch(pay1)
          {
            case some(pay2):
              assert [_]item_constraints(pay2, cs_pay, pub);
              item_constraints_injective(i, pay2, cs_pay);
            case none:
              open [_]ill_formed_item_chars(sig)(cs_pay);
              assert false;
          }
        }
    @*/
    //@ close item(item, i, pub);
  }
}