void AES_GCM_DECRYPT(octet *K,octet *IV,octet *H,octet *C,octet *P,octet *T)
{
	gcm g;
	gcm_init(&g,K->len,K->val,IV->len,IV->val);
	gcm_add_header(&g,H->val,H->len);
	gcm_add_cipher(&g,GCM_DECRYPTING,P->val,C->len,C->val);
	P->len=C->len;
	gcm_finish(&g,T->val); 
	T->len=16;
}
Exemplo n.º 2
0
int cipher_write_tag( cipher_context_t *ctx,
                      unsigned char *tag, size_t tag_len )
{
    if( NULL == ctx || NULL == ctx->cipher_info || NULL == tag )
        return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA );

    if( POLARSSL_ENCRYPT != ctx->operation )
        return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA );

    if( POLARSSL_MODE_GCM == ctx->cipher_info->mode )
        return gcm_finish( (gcm_context *) ctx->cipher_ctx, tag, tag_len );

    return( 0 );
}
Exemplo n.º 3
0
int cipher_check_tag( cipher_context_t *ctx,
                      const unsigned char *tag, size_t tag_len )
{
    int ret;

    if( NULL == ctx || NULL == ctx->cipher_info ||
        POLARSSL_DECRYPT != ctx->operation )
    {
        return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
    }

#if defined(POLARSSL_GCM_C)
    if( POLARSSL_MODE_GCM == ctx->cipher_info->mode )
    {
        unsigned char check_tag[16];
        size_t i;
        int diff;

        if( tag_len > sizeof( check_tag ) )
            return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;

        if( 0 != ( ret = gcm_finish( (gcm_context *) ctx->cipher_ctx,
                                     check_tag, tag_len ) ) )
        {
            return( ret );
        }

        /* Check the tag in "constant-time" */
        for( diff = 0, i = 0; i < tag_len; i++ )
            diff |= tag[i] ^ check_tag[i];

        if( diff != 0 )
            return( POLARSSL_ERR_CIPHER_AUTH_FAILED );

        return( 0 );
    }
#endif

    return( 0 );
}
/*! \brief Decrypt data using AES GCM
 *
 *  AES is run as a block cypher in the GCM  mode of operation. The key size is 128 bits.
 *  This function will decrypt any data length.
 *
 *  @param  key           128 bit secret key
 *  @param  IV            96 bit initialization vector
 *  @param  header        Additional authenticated data (AAD). This data is authenticated, but not decrypted.
 *  @param  ciphertext    Encrypted data.
 *  @return plaintext     Decrypted data. It is the same length as the ciphertext.
 *  @return tag           128 bit authentication tag.
 *  @return rtn           Returns 0 if successful or else an error code
 */
AESGCM_EXPORT int aesGcmDecrypt(char* key, char* IV, char* header, int headerLength,
                                char* ciphertext, int ciphertextLength, char* plaintext,
                                char* tag)
{
    gcm g;
    int keyLength=AS;
    int tagLength=AS;
    gcm_init(&g,keyLength,key,IVLength,IV);

    if(!gcm_add_header(&g,header,headerLength))
    {
        return AES_INIT_ERROR;
    }

    if(!gcm_add_cipher(&g,GCM_DECRYPTING,plaintext,ciphertextLength,ciphertext))
    {
        return AES_DECRYPT_ERROR;
    }

    gcm_finish(&g,tag);
    tagLength=16;
    return 0;
}
Exemplo n.º 5
0
PlaintextMessage EncryptedMessage::decrypt(const G2& P, const G2& Ppub, G1 D, PFC *pfc) {
    G2 uCalc;
    G2 U = (*autData).getU();
    Big ud_hash = (*pfc).hash_to_aes_key((*pfc).pairing(U,D));
    Big ses_key;
    Big r;
    int nbOfRecipients = (*autData).getNbOfRecipients();

    Big W;
    Big V = (*autData).getV();
    Big rho, rho_hash;
    vector <Big> ws = (*autData).getEncryptedRecipientKeys();
    char P_text[Clen];
    bool integrity = false;

    time_t begin_time = clock();

    int i = 0;
    while(U != uCalc && i < nbOfRecipients){
        // rho = V XOR Hash(e(D,U))
        W=ws.at(i);
        rho = lxor(W, ud_hash);

        // M = W XOR Hash(rho)
        (*pfc).start_hash();
        (*pfc).add_to_hash(rho);
        rho_hash = (*pfc).finish_hash_to_group();
        ses_key = lxor(V, rho_hash);

        // r = Hash(rho,M)
        (*pfc).start_hash();
        (*pfc).add_to_hash(rho);
        (*pfc).add_to_hash(ses_key);
        r = (*pfc).finish_hash_to_group();
        uCalc = (*pfc).mult(P,r);
        i++;
    }
    cout << "ses_key is " << endl << ses_key << endl;

    /*************************************************
    *       AES GCM part of the decryption step      *
    **************************************************/
    to_binary(ses_key, HASH_LEN, sessionKey, TRUE);
    char k1[HASH_LEN/2];
    char iv[HASH_LEN/2];
    char Tdec[TAG_LEN];
    memset(P_text, 0, Clen+1);

    getIV(iv);
    getK1(k1);

    int Alen = (*autData).getLength();
    char A[Alen];
    (*autData).encodeTo(A);
    gcm g;
    gcm_init(&g, HASH_LEN/2, k1, HASH_LEN/2, iv);
    gcm_add_header(&g, A, Alen);
    gcm_add_cipher(&g, GCM_DECRYPTING, P_text, Clen, C);
    gcm_finish(&g, Tdec);

    integrity = true;
    for (int j = 0; j < TAG_LEN; j++) {
        if(Tdec[j] != T[j]) {
            integrity = false;
        }
    }

    if(integrity == false) {
        cout << "Received tag T does not correspond to decrypted T. There are some integrity issues here." << endl;
    } else {
        cout << "Successful integrity check!" << endl;
    }

    message = (string)P_text;

    return PlaintextMessage(message);
}