/*
  Copyright (C) 2005, 2004, 2010, 2012 Erik Eliasson, Johan Bilien, Werner Dittmann

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations
 * including the two.
 * You must obey the GNU General Public License in all respects
 * for all of the code used other than OpenSSL.  If you modify
 * file(s) with this exception, you may extend this exception to your
 * version of the file(s), but you are not obligated to do so.  If you
 * do not wish to do so, delete this exception statement from your
 * version.  If you delete this exception statement from all source
 * files in the program, then also delete it here.
*/



#ifndef SRTPSYMCRYPTO_H
#define SRTPSYMCRYPTO_H

/**
 * @file SrtpSymCrypto.h
 * @brief Class which implements SRTP AES cryptographic functions
 * 
 * @ingroup GNU_ZRTP
 * @{
 */

#include <stdint.h>
#include <CryptoContext.h>

#ifndef SRTP_BLOCK_SIZE
#define SRTP_BLOCK_SIZE 16
#endif

typedef struct _f8_ctx {
    unsigned char *S;           ///< Intermetiade buffer
    unsigned char *ivAccent;    ///< second IV
    uint32_t J;                 ///< Counter
} F8_CIPHER_CTX;

/**
 * Implments the SRTP encryption modes as defined in RFC3711
 *
 * The SRTP specification defines two encryption modes, AES-CTR
 * (AES Counter mode) and AES-F8 mode. The AES-CTR is required,
 * AES-F8 is optional.
 *
 * Both modes are desinged to encrypt/decrypt data of arbitrary length
 * (with a specified upper limit, refer to RFC 3711). These modes do
 * <em>not</em> require that the amount of data to encrypt is a multiple
 * of the AES blocksize (16 bytes), no padding is necessary.
 *
 * The implementation uses the openSSL library as its cryptographic
 * backend.
 *
 * @author Erik Eliasson <eliasson@it.kth.se>
 * @author Johan Bilien <jobi@via.ecp.fr>
 * @author Werner Dittmann <Werner.Dittmann@t-online.de>
 */
class SrtpSymCrypto {
public:
    SrtpSymCrypto(int algo = SrtpEncryptionAESCM);

    /**
     * Constructor that initializes key data
     * 
     * @param key
     *     Pointer to key bytes.
     * @param key_length
     *     Number of key bytes.
     */
    SrtpSymCrypto(uint8_t* key, int32_t key_length, int algo = SrtpEncryptionAESCM);

    ~SrtpSymCrypto();

    /**
     * Encrypts the inpout to the output.
     *
     * Encrypts one input block to one output block. Each block
     * is 16 bytes according to the AES encryption algorithm used.
     *
     * @param input
     *    Pointer to input block, must be 16 bytes
     *
     * @param output
     *    Pointer to output block, must be 16 bytes
     */
    void encrypt( const uint8_t* input, uint8_t* output );

    /**
     * Set new key
     *
     * @param key
     *   Pointer to key data, must have at least a size of keyLength 
     *
     * @param keyLength
     *   Length of the key in bytes, must be 16, 24, or 32
     *
     * @return
     *   false if key could not set.
     */
    bool setNewKey(const uint8_t* key, int32_t keyLength);

    /**
     * Computes the cipher stream for AES CM mode.
     *
     * @param output
     *    Pointer to a buffer that receives the cipher stream. Must be
     *    at least <code>length</code> bytes long.
     *
     * @param length
     *    Number of cipher stream bytes to produce. Usually the same
     *    length as the data to be encrypted.
     *
     * @param iv
     *    The initialization vector as input to create the cipher stream.
     *    Refer to chapter 4.1.1 in RFC 3711.
     */
    void get_ctr_cipher_stream(uint8_t* output, uint32_t length, uint8_t* iv);

    /**
     * Counter-mode encryption.
     *
     * This method performs the AES CM encryption.
     *
     * @param input
     *    Pointer to input buffer, must be <code>inputLen</code> bytes.
     *
     * @param inputLen
     *    Number of bytes to process.
     *
     * @param output
     *    Pointer to output buffer, must be <code>inputLen</code> bytes.
     *
     * @param iv
     *    The initialization vector as input to create the cipher stream.
     *    Refer to chapter 4.1.1 in RFC 3711.
     */
    void ctr_encrypt(const uint8_t* input, uint32_t inputLen, uint8_t* output, uint8_t* iv );

    /**
     * Counter-mode encryption, in place.
     *
     * This method performs the AES CM encryption.
     *
     * @param data
     *    Pointer to input and output block, must be <code>dataLen</code>
     *    bytes.
     *
     * @param data_length
     *    Number of bytes to process.
     *
     * @param iv
     *    The initialization vector as input to create the cipher stream.
     *    Refer to chapter 4.1.1 in RFC 3711.
     */
    void ctr_encrypt(uint8_t* data, uint32_t data_length, uint8_t* iv );

    /**
     * Derive a AES context to compute the IV'.
     *
     * See chapter 4.1.2.1 in RFC 3711.
     *
     * @param f8Cipher
     *    Pointer to the AES context that will be used to encrypt IV to IV'
     *
     * @param key
     *    The master key
     *
     * @param keyLen
     *    Length of the master key.
     *
     * @param salt
     *   Master salt.
     *
     * @param saltLen
     *   length of master salt.
     */
    void f8_deriveForIV(SrtpSymCrypto* f8Cipher, uint8_t* key, int32_t keyLen, uint8_t* salt, int32_t saltLen);

    /**
     * AES F8 mode encryption, in place.
     *
     * This method performs the AES F8 encryption, see chapter 4.1.2
     * in RFC 3711.
     *
     * @param data
     *    Pointer to input and output block, must be <code>dataLen</code>
     *    bytes.
     *
     * @param dataLen
     *    Number of bytes to process.
     *
     * @param iv
     *    The initialization vector as input to create the cipher stream.
     *    Refer to chapter 4.1.1 in RFC 3711.
     *
     * @param f8Cipher
     *   An AES cipher context used to encrypt IV to IV'.
     */
    void f8_encrypt(const uint8_t* data, uint32_t dataLen, uint8_t* iv, SrtpSymCrypto* f8Cipher);

    /**
     * AES F8 mode encryption.
     *
     * This method performs the AES F8 encryption, see chapter 4.1.2
     * in RFC 3711.
     *
     * @param data
     *    Pointer to input and output block, must be <code>dataLen</code>
     *    bytes.
     *
     * @param dataLen
     *    Number of bytes to process.
     *
     * @param out
     *    Pointer to output buffer, must be <code>dataLen</code> bytes.
     *
     * @param iv
     *    The initialization vector as input to create the cipher stream.
     *    Refer to chapter 4.1.1 in RFC 3711.
     *
     * @param f8Cipher
     *   An AES cipher context used to encrypt IV to IV'.
     */
    void f8_encrypt(const uint8_t* data, uint32_t dataLen, uint8_t* out, uint8_t* iv, SrtpSymCrypto* f8Cipher);

private:
    int processBlock(F8_CIPHER_CTX* f8ctx, const uint8_t* in, int32_t length, uint8_t* out);
    void* key;
    int32_t algorithm;
};

#pragma GCC visibility push(default)
int testF8();
#pragma GCC visibility pop

/* Only SrtpSymCrypto functions define the MAKE_F8_TEST */
#ifdef MAKE_F8_TEST

#include <cstring>
#include <iostream>
#include <cstdio>
#include <arpa/inet.h>

using namespace std;

static void hexdump(const char* title, const unsigned char *s, int l)
{
    int n=0;

    if (s == NULL) return;

    fprintf(stderr, "%s",title);
    for( ; n < l ; ++n) {
        if((n%16) == 0)
            fprintf(stderr, "\n%04x",n);
        fprintf(stderr, " %02x",s[n]);
    }
    fprintf(stderr, "\n");
}

/*
 * The F8 test vectors according to RFC3711
 */
static unsigned char salt[] = {0x32, 0xf2, 0x87, 0x0d};

static unsigned char iv[] = {  0x00, 0x6e, 0x5c, 0xba, 0x50, 0x68, 0x1d, 0xe5,
                        0x5c, 0x62, 0x15, 0x99, 0xd4, 0x62, 0x56, 0x4a};

static unsigned char key[]= {  0x23, 0x48, 0x29, 0x00, 0x84, 0x67, 0xbe, 0x18,
                        0x6c, 0x3d, 0xe1, 0x4a, 0xae, 0x72, 0xd6, 0x2c};

static unsigned char payload[] = {
                        0x70, 0x73, 0x65, 0x75, 0x64, 0x6f, 0x72, 0x61,
                        0x6e, 0x64, 0x6f, 0x6d, 0x6e, 0x65, 0x73, 0x73,
                        0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20,
                        0x6e, 0x65, 0x78, 0x74, 0x20, 0x62, 0x65, 0x73,
                        0x74, 0x20, 0x74, 0x68, 0x69, 0x6e, 0x67};  // 39 bytes

static unsigned char cipherText[] = {
                        0x01, 0x9c, 0xe7, 0xa2, 0x6e, 0x78, 0x54, 0x01,
                        0x4a, 0x63, 0x66, 0xaa, 0x95, 0xd4, 0xee, 0xfd,
                        0x1a, 0xd4, 0x17, 0x2a, 0x14, 0xf9, 0xfa, 0xf4,
                        0x55, 0xb7, 0xf1, 0xd4, 0xb6, 0x2b, 0xd0, 0x8f,
                        0x56, 0x2c, 0x0e, 0xef, 0x7c, 0x48, 0x02}; // 39 bytes

// static unsigned char rtpPacketHeader[] = {
//                         0x80, 0x6e, 0x5c, 0xba, 0x50, 0x68, 0x1d, 0xe5,
//                         0x5c, 0x62, 0x15, 0x99};

static unsigned char rtpPacket[] = {
                    0x80, 0x6e, 0x5c, 0xba, 0x50, 0x68, 0x1d, 0xe5,
                    0x5c, 0x62, 0x15, 0x99,                        // header
                    0x70, 0x73, 0x65, 0x75, 0x64, 0x6f, 0x72, 0x61, // payload
                    0x6e, 0x64, 0x6f, 0x6d, 0x6e, 0x65, 0x73, 0x73,
                    0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20,
                    0x6e, 0x65, 0x78, 0x74, 0x20, 0x62, 0x65, 0x73,
                    0x74, 0x20, 0x74, 0x68, 0x69, 0x6e, 0x67};
static uint32_t ROC = 0xd462564a;

int testF8()
{
    SrtpSymCrypto* aesCipher = new SrtpSymCrypto(SrtpEncryptionAESF8);
    SrtpSymCrypto* f8AesCipher = new SrtpSymCrypto(SrtpEncryptionAESF8);

    aesCipher->setNewKey(key, sizeof(key));

    /* Create the F8 IV (refer to chapter 4.1.2.2 in RFC 3711):
     *
     * IV = 0x00 || M || PT || SEQ  ||      TS    ||    SSRC   ||    ROC
     *      8Bit  1bit  7bit  16bit       32bit        32bit        32bit
     * ------------\     /--------------------------------------------------
     *       XX       XX      XX XX   XX XX XX XX   XX XX XX XX  XX XX XX XX
     */

    unsigned char derivedIv[16];
    uint32_t* ui32p = (uint32_t*)derivedIv;

    memcpy(derivedIv, rtpPacket, 12);
    derivedIv[0] = 0;

    // set ROC in network order into IV
    ui32p[3] = htonl(ROC);

    int32_t pad = 0;

    if (memcmp(iv, derivedIv, 16) != 0) {
        cerr << "Wrong IV constructed" << endl;
        hexdump("derivedIv", derivedIv, 16);
        hexdump("test vector Iv", iv, 16);
        return -1;
    }

    aesCipher->f8_deriveForIV(f8AesCipher, key, sizeof(key), salt, sizeof(salt));

    // now encrypt the RTP payload data
    aesCipher->f8_encrypt(rtpPacket + 12, sizeof(rtpPacket)-12+pad,
        derivedIv, f8AesCipher);

    // compare with test vector cipher data
    if (memcmp(rtpPacket+12, cipherText, sizeof(rtpPacket)-12+pad) != 0) {
        cerr << "cipher data mismatch" << endl;
        hexdump("computed cipher data", rtpPacket+12, sizeof(rtpPacket)-12+pad);
        hexdump("Test vcetor cipher data", cipherText, sizeof(cipherText));
        return -1;
    }

    // Now decrypt the data to get the payload data again
    aesCipher->f8_encrypt(rtpPacket+12, sizeof(rtpPacket)-12+pad, derivedIv, f8AesCipher);

    // compare decrypted data with test vector payload data
    if (memcmp(rtpPacket+12, payload, sizeof(rtpPacket)-12+pad) != 0) {
        cerr << "payload data mismatch" << endl;
        hexdump("computed payload data", rtpPacket+12, sizeof(rtpPacket)-12+pad);
        hexdump("Test vector payload data", payload, sizeof(payload));
        return -1;
    }
    return 0;
}
#endif

/**
 * @}
 */

#endif

/** EMACS **
 * Local variables:
 * mode: c++
 * c-default-style: ellemtel
 * c-basic-offset: 4
 * End:
 */

