/**********
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 3 of the License, or (at your
option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)

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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
**********/
// Copyright (c) 1996-2020 Live Networks, Inc.  All rights reserved.
// The SRTP 'Cryptographic Context', used in all of our uses of SRTP.
// Definition

#ifndef _SRTP_CRYPTOGRAPHIC_CONTEXT_HH
#define _SRTP_CRYPTOGRAPHIC_CONTEXT_HH

#ifndef _MIKEY_HH
#include "MIKEY.hh"
#endif

class SRTPCryptographicContext {
public:
  SRTPCryptographicContext(MIKEYState const& mikeyState);
  virtual ~SRTPCryptographicContext();

  // Authenticate (if necessary) and decrypt (if necessary) incoming SRTP and SRTCP packets.
  // Returns True iff the packet is well-formed and authenticates OK.
  // ("outPacketSize" will be <= "inPacketSize".)
  Boolean processIncomingSRTPPacket(u_int8_t* buffer, unsigned inPacketSize,
				    unsigned& outPacketSize);
  Boolean processIncomingSRTCPPacket(u_int8_t* buffer, unsigned inPacketSize,
				     unsigned& outPacketSize);

  // Encrypt (if necessary) and add an authentication tag (if necessary) to an outgoing
  // RTCP packet.
  // Returns True iff the packet is well-formed.
  // ("outPacketSize" will be >= "inPacketSize"; there must be enough space at the end of
  //  "buffer" for the extra SRTCP tags (4+4+10 bytes).)
  Boolean processOutgoingSRTCPPacket(u_int8_t* buffer, unsigned inPacketSize,
				      unsigned& outPacketSize);

#ifndef NO_OPENSSL
private:
  // Definitions specific to the "SRTP_AES128_CM_HMAC_SHA1_80" ciphersuite.
  // Later generalize to support more SRTP ciphersuites #####
#define SRTP_CIPHER_KEY_LENGTH (128/8) // in bytes
#define SRTP_CIPHER_SALT_LENGTH (112/8) // in bytes
#define SRTP_MKI_LENGTH 4 // in bytes
#define SRTP_AUTH_KEY_LENGTH (160/8) // in bytes
#define SRTP_AUTH_TAG_LENGTH (80/8) // in bytes

  struct derivedKeys {
    u_int8_t cipherKey[SRTP_CIPHER_KEY_LENGTH];
    u_int8_t salt[SRTP_CIPHER_SALT_LENGTH];
    u_int8_t authKey[SRTP_AUTH_KEY_LENGTH];
  };

  struct allDerivedKeys {
    derivedKeys srtp;
    derivedKeys srtcp;
  };

  typedef enum {
		label_srtp_encryption  = 0x00,
		label_srtp_msg_auth    = 0x01,
		label_srtp_salt        = 0x02,
		label_srtcp_encryption = 0x03,
		label_srtcp_msg_auth   = 0x04,
		label_srtcp_salt       = 0x05
  } SRTPKeyDerivationLabel;

  unsigned generateSRTCPAuthenticationTag(u_int8_t const* dataToAuthenticate, unsigned numBytesToAuthenticate,
					  u_int8_t* resultAuthenticationTag);
      // returns the size of the resulting authentication tag

  Boolean verifySRTPAuthenticationTag(u_int8_t* dataToAuthenticate, unsigned numBytesToAuthenticate,
				      u_int32_t roc, u_int8_t const* authenticationTag);
  Boolean verifySRTCPAuthenticationTag(u_int8_t const* dataToAuthenticate, unsigned numBytesToAuthenticate,
				       u_int8_t const* authenticationTag);

  void decryptSRTPPacket(u_int64_t index, u_int32_t ssrc, u_int8_t* data, unsigned numDataBytes);
  void decryptSRTCPPacket(u_int32_t index, u_int32_t ssrc, u_int8_t* data, unsigned numDataBytes);

  void encryptSRTCPPacket(u_int32_t index, u_int32_t ssrc, u_int8_t* data, unsigned numDataBytes);

  unsigned generateAuthenticationTag(derivedKeys& keysToUse,
				     u_int8_t const* dataToAuthenticate, unsigned numBytesToAuthenticate,
				     u_int8_t* resultAuthenticationTag);
      // returns the size of the resulting authentication tag
      // "resultAuthenticationTag" must point to an array of at least SRTP_AUTH_TAG_LENGTH
  Boolean verifyAuthenticationTag(derivedKeys& keysToUse,
				  u_int8_t const* dataToAuthenticate, unsigned numBytesToAuthenticate,
				  u_int8_t const* authenticationTag);

  void cryptData(derivedKeys& keys, u_int64_t index, u_int32_t ssrc,
		 u_int8_t* data, unsigned numDataBytes);

  void performKeyDerivation();

  void deriveKeysFromMaster(u_int8_t const* masterKey, u_int8_t const* salt,
			    allDerivedKeys& allKeysResult);
      // used to implement "performKeyDerivation()"
  void deriveSingleKey(u_int8_t const* masterKey, u_int8_t const* salt,
		       SRTPKeyDerivationLabel label,
		       unsigned resultKeyLength, u_int8_t* resultKey);
      // used to implement "deriveKeysFromMaster()".
      // ("resultKey" must be an existing buffer, of size >= "resultKeyLength")

private:
  MIKEYState const& fMIKEYState;

  // Master key + salt:
  u_int8_t const* masterKeyPlusSalt() const { return fMIKEYState.keyData(); }

  u_int8_t const* masterKey() const { return &masterKeyPlusSalt()[0]; }
  u_int8_t const* masterSalt() const { return &masterKeyPlusSalt()[SRTP_CIPHER_KEY_LENGTH]; }

  Boolean weEncryptSRTP() const { return fMIKEYState.encryptSRTP(); }
  Boolean weEncryptSRTCP() const { return fMIKEYState.encryptSRTCP(); }
  Boolean weAuthenticate() const { return fMIKEYState.useAuthentication(); }
  u_int32_t MKI() const { return fMIKEYState.MKI(); }

  // Derived (i.e., session) keys:
  allDerivedKeys fDerivedKeys;

  // State used for handling the reception of SRTP packets:
  Boolean fHaveReceivedSRTPPackets;
  u_int16_t fPreviousHighRTPSeqNum;
  u_int32_t fROC; // rollover counter

  // State used for handling the sending of SRTCP packets:
  u_int32_t fSRTCPIndex;
#endif
};

#endif
