/*
 *  Copyright 2014 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "pc/external_hmac.h"

#include <stdlib.h>  // For malloc/free.
#include <string.h>

#include <cstdint>

#include "rtc_base/logging.h"
#include "rtc_base/zero_memory.h"
#include "third_party/libsrtp/crypto/include/auth.h"
#include "third_party/libsrtp/include/srtp.h"

// Begin test case 0 */
static const uint8_t kExternalHmacTestCase0Key[20] = {
    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};

static const uint8_t kExternalHmacTestCase0Data[8] = {
    0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65  // "Hi There"
};

static const uint8_t kExternalHmacFakeTag[10] = {0xba, 0xdd, 0xba, 0xdd, 0xba,
                                                 0xdd, 0xba, 0xdd, 0xba, 0xdd};

static const srtp_auth_test_case_t kExternalHmacTestCase0 = {
    20,                                                // Octets in key
    const_cast<uint8_t*>(kExternalHmacTestCase0Key),   // Key
    8,                                                 // Octets in data
    const_cast<uint8_t*>(kExternalHmacTestCase0Data),  // Data
    10,                                                // Octets in tag
    const_cast<uint8_t*>(kExternalHmacFakeTag),        // Tag
    nullptr                                            // Pointer to next
                                                       // testcase
};

static const char kExternalHmacDescription[] =
    "external hmac sha-1 authentication";

// srtp_auth_type_t external_hmac is the hmac metaobject

static const srtp_auth_type_t external_hmac = {
    external_hmac_alloc,
    external_hmac_dealloc,
    external_hmac_init,
    external_hmac_compute,
    external_hmac_update,
    external_hmac_start,
    const_cast<char*>(kExternalHmacDescription),
    const_cast<srtp_auth_test_case_t*>(&kExternalHmacTestCase0),
    EXTERNAL_HMAC_SHA1};

srtp_err_status_t external_hmac_alloc(srtp_auth_t** a,
                                      int key_len,
                                      int out_len) {
  uint8_t* pointer;

  // Check key length - note that we don't support keys larger
  // than 20 bytes yet
  if (key_len > 20)
    return srtp_err_status_bad_param;

  // Check output length - should be less than 20 bytes/
  if (out_len > 20)
    return srtp_err_status_bad_param;

  // Allocate memory for auth and hmac_ctx_t structures.
  pointer = new uint8_t[(sizeof(ExternalHmacContext) + sizeof(srtp_auth_t))];
  if (pointer == nullptr)
    return srtp_err_status_alloc_fail;

  // Set pointers
  *a = reinterpret_cast<srtp_auth_t*>(pointer);
  // `external_hmac` is const and libsrtp expects `type` to be non-const.
  // const conversion is required. `external_hmac` is constant because we don't
  // want to increase global count in Chrome.
  (*a)->type = const_cast<srtp_auth_type_t*>(&external_hmac);
  (*a)->state = pointer + sizeof(srtp_auth_t);
  (*a)->out_len = out_len;
  (*a)->key_len = key_len;
  (*a)->prefix_len = 0;

  return srtp_err_status_ok;
}

srtp_err_status_t external_hmac_dealloc(srtp_auth_t* a) {
  webrtc::ExplicitZeroMemory(a,
                             sizeof(ExternalHmacContext) + sizeof(srtp_auth_t));

  // Free memory
  delete[] a;

  return srtp_err_status_ok;
}

srtp_err_status_t external_hmac_init(void* state,
                                     const uint8_t* key,
                                     int key_len) {
  if (key_len > HMAC_KEY_LENGTH)
    return srtp_err_status_bad_param;

  ExternalHmacContext* context = static_cast<ExternalHmacContext*>(state);
  memcpy(context->key, key, key_len);
  context->key_length = key_len;
  return srtp_err_status_ok;
}

srtp_err_status_t external_hmac_start(void* /*state*/) {
  return srtp_err_status_ok;
}

srtp_err_status_t external_hmac_update(void* /*state*/,
                                       const uint8_t* /*message*/,
                                       int /*msg_octets*/) {
  return srtp_err_status_ok;
}

srtp_err_status_t external_hmac_compute(void* /*state*/,
                                        const uint8_t* /*message*/,
                                        int /*msg_octets*/,
                                        int tag_len,
                                        uint8_t* result) {
  memcpy(result, kExternalHmacFakeTag, tag_len);
  return srtp_err_status_ok;
}

srtp_err_status_t external_crypto_init() {
  // `external_hmac` is const. const_cast is required as libsrtp expects
  // non-const.
  srtp_err_status_t status = srtp_replace_auth_type(
      const_cast<srtp_auth_type_t*>(&external_hmac), EXTERNAL_HMAC_SHA1);
  if (status) {
    RTC_LOG(LS_ERROR) << "Error in replacing default auth module, error: "
                      << status;
    return srtp_err_status_fail;
  }
  return srtp_err_status_ok;
}
