예제 #1
0
파일: gcmtest.c 프로젝트: ramriot/libsqrl
/*******************************************************************************
 *
 *  VERIFY_BAD_DECRYPTION
 *
 *  Handles block type 2:  This is the third of the three routines, called by
 *  VERIFY_GCM, which reads the "gcm_test_vectors.bin" file block by block.
 *  It invokes the AES-GCM library "gcm_auth_decrypt" function to decrypt the
 *  provided ciphertext, then verifies a AUTHENTICATION FAILURE caused by a
 *  deliberate mismatch in the ciphertext and/or authentication data which was
 *  provided by the NIST file(s).
 */
int verify_bad_decryption(
        const uchar *key,       // pointer to the cipher key
        size_t key_len,         // byte length of the key
        const uchar *iv,        // pointer to the initialization vector
        size_t iv_len,          // byte length of the initialization vector
        const uchar *aad,       // pointer to the non-ciphered additional data
        size_t aad_len,         // byte length of the additional AEAD data
        const uchar *ct,        // pointer to the CORRECT cipher data
        size_t ct_len,          // byte length of the cipher data
        const uchar *tag,       // pointer to the CORRECT tag to be generated
        size_t tag_len )        // byte length of the tag to be generated
{
    int ret = 0;                // our return value
    gcm_context ctx;            // includes the AES context structure
    uchar pt_buf[256];          // plaintext results for comparison

    gcm_setkey( &ctx, key, (const uint)key_len );   // setup our AES-GCM key

    // decrypt the NIST-provided ciphertext and auth tag into the local pt_buf
    ret = gcm_auth_decrypt( &ctx, iv, iv_len, aad, aad_len,
                             ct, pt_buf, ct_len, tag, tag_len);
    ret ^= GCM_AUTH_FAILURE;    // the fucntion SHOULD FAIL and return the
                                // GCM_AUTH_FAILURE. We XOR it to verify
    gcm_zero_ctx( &ctx );

    return ( ret );             // return any error 'XOR' generated above
}
예제 #2
0
/*
 * Packet-oriented decryption for AEAD modes
 */
int cipher_auth_decrypt( cipher_context_t *ctx,
                         const unsigned char *iv, size_t iv_len,
                         const unsigned char *ad, size_t ad_len,
                         const unsigned char *input, size_t ilen,
                         unsigned char *output, size_t *olen,
                         const unsigned char *tag, size_t tag_len )
{
#if defined(POLARSSL_GCM_C)
    if( POLARSSL_MODE_GCM == ctx->cipher_info->mode )
    {
        int ret;

        *olen = ilen;
        ret = gcm_auth_decrypt( ctx->cipher_ctx, ilen,
                                iv, iv_len, ad, ad_len,
                                tag, tag_len, input, output );

        if( ret == POLARSSL_ERR_GCM_AUTH_FAILED )
            ret = POLARSSL_ERR_CIPHER_AUTH_FAILED;

        return( ret );
    }
#endif /* POLARSSL_GCM_C */
#if defined(POLARSSL_CCM_C)
    if( POLARSSL_MODE_CCM == ctx->cipher_info->mode )
    {
        int ret;

        *olen = ilen;
        ret = ccm_auth_decrypt( ctx->cipher_ctx, ilen,
                                iv, iv_len, ad, ad_len,
                                input, output, tag, tag_len );

        if( ret == POLARSSL_ERR_CCM_AUTH_FAILED )
            ret = POLARSSL_ERR_CIPHER_AUTH_FAILED;

        return( ret );
    }
#endif /* POLARSSL_CCM_C */

    return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE );
}
/**
 * @Brief AES-GCM decrypt, compute authentication tag and compare it to the one provided
 *
 * @param[in]	key							Encryption key
 * @param[in]	keyLength					Key buffer length, in bytes, must be 16,24 or 32
 * @param[in]	cipherText					Buffer to be decrypted
 * @param[in]	cipherTextLength			Length in bytes of buffer to be decrypted
 * @param[in]	authenticatedData			Buffer holding additional data to be used in auth tag computation
 * @param[in]	authenticatedDataLength		Additional data length in bytes
 * @param[in]	initializationVector		Buffer holding the initialisation vector
 * @param[in]	initializationVectorLength	Initialisation vector length in bytes
 * @param[in]	tag							Buffer holding the authentication tag
 * @param[in]	tagLength					Length in bytes for the authentication tag
 * @param[out]	output						Buffer holding the output, shall be at least the length of cipherText buffer
 *
 * @return 0 on succes, BCTBX_ERROR_AUTHENTICATION_FAILED if tag doesn't match or polarssl error code
 */
int32_t bctbx_aes_gcm_decrypt_and_auth(const uint8_t *key, size_t keyLength,
		const uint8_t *cipherText, size_t cipherTextLength,
		const uint8_t *authenticatedData, size_t authenticatedDataLength,
		const uint8_t *initializationVector, size_t initializationVectorLength,
		const uint8_t *tag, size_t tagLength,
		uint8_t *output) {
	gcm_context gcmContext;
	int ret;

	ret = gcm_init(&gcmContext, key, keyLength*8);
	if (ret != 0) return ret;

	ret = gcm_auth_decrypt(&gcmContext, cipherTextLength, initializationVector, initializationVectorLength, authenticatedData, authenticatedDataLength, tag, tagLength, cipherText, output);

	if (ret == POLARSSL_ERR_GCM_AUTH_FAILED) {
		return BCTBX_ERROR_AUTHENTICATION_FAILED;
	}

	return ret;
}
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;
}
int app_receive(char *key, char **message)
  /*@ requires [?f0]polarssl_world(sc_auth_polarssl_pub) &*&
               [?f1]polarssl_cryptogram(key, KEY_BYTE_SIZE, ?key_cs, ?key_cg) &*&
                 key_cg == polarssl_symmetric_key(?creator, ?key_id) &*&
               pointer(message, _);
  @*/
  /*@ ensures  [f0]polarssl_world(sc_auth_polarssl_pub) &*&
               [f1]polarssl_cryptogram(key, KEY_BYTE_SIZE, key_cs, key_cg) &*&
               pointer(message, ?message_p) &*&
               malloc_block(message_p, result) &*&
               chars(message_p, result, ?m_cs) &*&
               bad(creator) ?
                 [_]polarssl_public_generated_chars(sc_auth_polarssl_pub)(m_cs)
               : 
                 true == app_send_event(creator, m_cs);
  @*/
{
  int socket1;
  int socket2;
  int size;
  int result_size;
  char buffer[POLARSSL_MAX_MESSAGE_BYTE_SIZE];

  char iv[16];
  char tag[16];
  char* encrypted;
  char* decrypted;

  // Receive message
  if(net_bind(&socket1, NULL, APP_RECEIVE_PORT) != 0)
    abort();
  if(net_accept(socket1, &socket2, NULL) != 0)
    abort();
  if(net_set_block(socket2) != 0)
    abort();
    
  size = net_recv(&socket2, buffer, POLARSSL_MAX_MESSAGE_BYTE_SIZE);
  if (size < 16 + POLARSSL_MIN_ENCRYPTED_BYTE_SIZE + 16)
    abort();
  //@ open polarssl_public_message(sc_auth_polarssl_pub)(buffer, size, ?cs);
  //@ close [1/2]hide_chars(buffer, size, cs);
  result_size = size - 16 - 16;
  encrypted = malloc(result_size);
  if (encrypted == 0) abort();
  decrypted = malloc(result_size);
  if (decrypted == 0) abort();
  
  // Extract parts of message
  memcpy(iv, buffer, 16);
  memcpy(encrypted, (void*) buffer + 16, (unsigned int) result_size);
  memcpy(tag, (void*) buffer + 16 + result_size, 16);
  //@ assert chars(iv, 16, ?iv_cs);
  //@ assert chars(encrypted, result_size, ?e_cs);
  //@ assert chars(tag, 16, ?t_cs);
  //@ chars_join(buffer);
  //@ chars_join(buffer);
  //@ open [1/2]hide_chars(buffer, size, cs);
  //@ close [1/2]hide_chars(buffer, size, cs);
  //@ assert cs == append(iv_cs, append(e_cs, t_cs));

  // Decrypt message
  {
    gcm_context gcm_context;
    //@ close gcm_context(&gcm_context);
    //@ open [f1]polarssl_cryptogram(key, KEY_BYTE_SIZE, key_cs, key_cg);
    //@ close polarssl_key_id(creator, key_id);
    if (gcm_init(&gcm_context, POLARSSL_AES_CIPHER_ID, key, 
                (unsigned int) KEY_BYTE_SIZE * 8) != 0) abort();
    /*@ assert gcm_context_initialized(&gcm_context, 
                                       some(pair(creator, key_id))); @*/
    //@ close [f1]polarssl_cryptogram(key, KEY_BYTE_SIZE, key_cs, key_cg);

    //@ polarssl_public_generated_chars_split(sc_auth_polarssl_pub, cs, 16);
    /*@ polarssl_public_generated_chars_split(
                     sc_auth_polarssl_pub, append(e_cs, t_cs), result_size); @*/
    //@ assert chars(encrypted, result_size, e_cs);
    if (gcm_auth_decrypt(&gcm_context, (unsigned int) result_size,
                         iv, 16, NULL, 0, tag, 16,
                         encrypted, decrypted) != 0) abort();
    gcm_free(&gcm_context);
    //@ open gcm_context(&gcm_context);
  }
  
  //@ assert chars(decrypted, result_size, ?dec_cs);
  //@ chars_join(buffer);
  //@ open [1/2]hide_chars(buffer, size, cs);

  /*@ polarssl_cryptogram e_cg = polarssl_auth_encrypted(
                                      creator, key_id, t_cs, dec_cs, iv_cs); @*/
  //@ assert e_cs == polarssl_chars_for_cryptogram(e_cg);
  //@ polarssl_cryptogram_constraints(e_cs, e_cg);
  /*@ polarssl_public_generated_chars_extract(
                                          sc_auth_polarssl_pub, e_cs, e_cg); @*/
  //@ open [_]sc_auth_polarssl_pub(e_cg);
  /*@ if (!bad(creator))
      {
        assert true == app_send_event(creator, dec_cs);
      }
      else
      {
        assert [_]polarssl_public_generated_chars(sc_auth_polarssl_pub)(dec_cs);
      }
  @*/

  net_close(socket1);
  net_close(socket2);
  
  free(encrypted);
  *message = decrypted;
  return result_size;
}
예제 #6
0
void attacker_send_auth_decrypted(havege_state *havege_state, void* socket)
  //@ requires attacker_invariant(?pub, ?pred, ?kc, havege_state, socket, ?attacker);
  //@ ensures  attacker_invariant(pub, pred, kc, havege_state, socket, attacker);
{
  int temp;
  int size1;
  int size2;
  char buffer1[MAX_MESSAGE_SIZE];
  char buffer2[MAX_MESSAGE_SIZE];
  char buffer3[MAX_MESSAGE_SIZE];
  gcm_context gcm_context;
  char iv[16];

  //@ open attacker_invariant(pub, pred, kc, havege_state, socket, attacker);

  size1 = net_recv(socket, buffer1, MAX_MESSAGE_SIZE);
  size2 = net_recv(socket, buffer2, MAX_MESSAGE_SIZE);
  if (size1 <= 16 || size2 <= 16 ||
      (size1 != 16 && size1 != 24 && size1 != 32))
  {
    //@ close attacker_invariant(pub, pred, kc, havege_state, socket, attacker);
    return;
  }

  //@ close gcm_context(&gcm_context);
  //@ interpret_symmetric_key(buffer1, size1);
  //@ assert cryptogram(buffer1, size1, ?ccs1, ?cg_key);
  //@ assert cg_key == cg_symmetric_key(?p, ?c);
  if (gcm_init(&gcm_context, POLARSSL_CIPHER_ID_AES,
      buffer1, (unsigned int) size1 * 8) == 0)
  {
    if (get_iv(havege_state, iv) == 0)
    {
      //@ assert crypto_chars(normal, iv, 16, ?ccs_iv);
      //@ assert chars(buffer2, size2, ?cs2);
      //@ interpret_auth_encrypted(buffer2, size2);
      //@ open cryptogram(buffer2, size2, ?ccs2, ?cg_enc);
      //@ cs_to_ccs_crypto_chars(buffer2, cs2);
      //@ chars_to_crypto_chars(buffer2, size2);
      //@ close exists(cg_enc);
      //@ assert cg_enc == cg_auth_encrypted(?p2, ?c2, ?ccs_output2, ?ccs_iv2);
      //@ crypto_chars_split(buffer2, 16);
      if (gcm_auth_decrypt(&gcm_context, (unsigned int) size2 - 16,
                            iv, 16, NULL, 0, buffer2, 16,
                            (void*) buffer2 + 16, buffer3) == 0)
      {
        /*@ if (!col)
            {
              assert crypto_chars(secret, buffer3, size2 - 16, ?ccs_output);
              ccs_output == ccs_output2;
              ccs_iv == ccs_iv2;
              assert ccs2 == ccs_for_cg(cg_enc);
              assert [_]pub(cg_enc);
              assert is_public_auth_decryption_is_public(?proof3, pub, pred);
              proof3(cg_key, cg_enc);
              public_crypto_chars(buffer3, size2 - 16);
              chars_to_crypto_chars(buffer3, size2 - 16);
            }
        @*/
        zeroize(iv, 16);
        //@ chars_to_crypto_chars(iv, 16);
      }
      //@ crypto_chars_to_chars(buffer3, size2 - 16);
      net_send(socket, buffer3, (unsigned int) size2 - 16);
      //@ crypto_chars_to_chars(buffer2, 16);
      //@ crypto_chars_to_chars((void*) buffer2 + 16, size2 - 16);
      //@ chars_join(buffer2);
    }
    //@ crypto_chars_to_chars(iv, 16);
    gcm_free(&gcm_context);
  }
  //@ open gcm_context(&gcm_context);
  //@ close attacker_invariant(pub, pred, kc, havege_state, socket, attacker);
  //@ public_cryptogram(buffer1, cg_key);
}