/**
 * @file
 * SNMPv3 crypto/auth functions implemented for ARM mbedtls.
 */

/*
 * Copyright (c) 2016 Elias Oenal and Dirk Ziegelmeier.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGE.
 *
 * Author: Elias Oenal <lwip@eliasoenal.com>
 *         Dirk Ziegelmeier <dirk@ziegelmeier.net>
 */

#include "lwip/apps/snmpv3.h"
#include "snmpv3_priv.h"
#include "lwip/arch.h"
#include "snmp_msg.h"
#include "lwip/sys.h"
#include <string.h>

#if LWIP_SNMP && LWIP_SNMP_V3 && LWIP_SNMP_V3_MBEDTLS

#include "mbedtls/md.h"
#include "mbedtls/cipher.h"

#include "mbedtls/md5.h"
#include "mbedtls/sha1.h"

err_t
snmpv3_auth(struct snmp_pbuf_stream *stream, u16_t length,
            const u8_t *key, snmpv3_auth_algo_t algo, u8_t *hmac_out)
{
  u32_t i;
  u8_t key_len;
  const mbedtls_md_info_t *md_info;
  mbedtls_md_context_t ctx;
  struct snmp_pbuf_stream read_stream;
  snmp_pbuf_stream_init(&read_stream, stream->pbuf, stream->offset, stream->length);

  if (algo == SNMP_V3_AUTH_ALGO_MD5) {
    md_info = mbedtls_md_info_from_type(MBEDTLS_MD_MD5);
    key_len = SNMP_V3_MD5_LEN;
  } else if (algo == SNMP_V3_AUTH_ALGO_SHA) {
    md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
    key_len = SNMP_V3_SHA_LEN;
  } else {
    return ERR_ARG;
  }

  mbedtls_md_init(&ctx);
  if (mbedtls_md_setup(&ctx, md_info, 1) != 0) {
    return ERR_ARG;
  }

  if (mbedtls_md_hmac_starts(&ctx, key, key_len) != 0) {
    goto free_md;
  }

  for (i = 0; i < length; i++) {
    u8_t byte;

    if (snmp_pbuf_stream_read(&read_stream, &byte)) {
      goto free_md;
    }

    if (mbedtls_md_hmac_update(&ctx, &byte, 1) != 0) {
      goto free_md;
    }
  }

  if (mbedtls_md_hmac_finish(&ctx, hmac_out) != 0) {
    goto free_md;
  }

  mbedtls_md_free(&ctx);
  return ERR_OK;

free_md:
  mbedtls_md_free(&ctx);
  return ERR_ARG;
}

#if LWIP_SNMP_V3_CRYPTO

err_t
snmpv3_crypt(struct snmp_pbuf_stream *stream, u16_t length,
             const u8_t *key, const u8_t *priv_param, const u32_t engine_boots,
             const u32_t engine_time, snmpv3_priv_algo_t algo, snmpv3_priv_mode_t mode)
{
  size_t i;
  mbedtls_cipher_context_t ctx;
  const mbedtls_cipher_info_t *cipher_info;

  struct snmp_pbuf_stream read_stream;
  struct snmp_pbuf_stream write_stream;
  snmp_pbuf_stream_init(&read_stream, stream->pbuf, stream->offset, stream->length);
  snmp_pbuf_stream_init(&write_stream, stream->pbuf, stream->offset, stream->length);
  mbedtls_cipher_init(&ctx);

  if (algo == SNMP_V3_PRIV_ALGO_DES) {
    u8_t iv_local[8];
    u8_t out_bytes[8];
    size_t out_len;

    /* RFC 3414 mandates padding for DES */
    if ((length & 0x07) != 0) {
      return ERR_ARG;
    }

    cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_DES_CBC);
    if (mbedtls_cipher_setup(&ctx, cipher_info) != 0) {
      return ERR_ARG;
    }
    if (mbedtls_cipher_set_padding_mode(&ctx, MBEDTLS_PADDING_NONE) != 0) {
      return ERR_ARG;
    }
    if (mbedtls_cipher_setkey(&ctx, key, 8 * 8, (mode == SNMP_V3_PRIV_MODE_ENCRYPT) ? MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT) != 0) {
      goto error;
    }

    /* Prepare IV */
    for (i = 0; i < LWIP_ARRAYSIZE(iv_local); i++) {
      iv_local[i] = priv_param[i] ^ key[i + 8];
    }
    if (mbedtls_cipher_set_iv(&ctx, iv_local, LWIP_ARRAYSIZE(iv_local)) != 0) {
      goto error;
    }

    for (i = 0; i < length; i += 8) {
      size_t j;
      u8_t in_bytes[8];
      out_len = LWIP_ARRAYSIZE(out_bytes) ;

      for (j = 0; j < LWIP_ARRAYSIZE(in_bytes); j++) {
        if (snmp_pbuf_stream_read(&read_stream, &in_bytes[j]) != ERR_OK) {
          goto error;
        }
      }

      if (mbedtls_cipher_update(&ctx, in_bytes, LWIP_ARRAYSIZE(in_bytes), out_bytes, &out_len) != 0) {
        goto error;
      }

      if (snmp_pbuf_stream_writebuf(&write_stream, out_bytes, (u16_t)out_len) != ERR_OK) {
        goto error;
      }
    }

    out_len = LWIP_ARRAYSIZE(out_bytes);
    if (mbedtls_cipher_finish(&ctx, out_bytes, &out_len) != 0) {
      goto error;
    }

    if (snmp_pbuf_stream_writebuf(&write_stream, out_bytes, (u16_t)out_len) != ERR_OK) {
      goto error;
    }
  } else if (algo == SNMP_V3_PRIV_ALGO_AES) {
    u8_t iv_local[16];

    cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_CFB128);
    if (mbedtls_cipher_setup(&ctx, cipher_info) != 0) {
      return ERR_ARG;
    }
    if (mbedtls_cipher_setkey(&ctx, key, 16 * 8, (mode == SNMP_V3_PRIV_MODE_ENCRYPT) ? MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT) != 0) {
      goto error;
    }

    /*
     * IV is the big endian concatenation of boots,
     * uptime and priv param - see RFC3826.
     */
    iv_local[0 + 0] = (engine_boots >> 24) & 0xFF;
    iv_local[0 + 1] = (engine_boots >> 16) & 0xFF;
    iv_local[0 + 2] = (engine_boots >>  8) & 0xFF;
    iv_local[0 + 3] = (engine_boots >>  0) & 0xFF;
    iv_local[4 + 0] = (engine_time  >> 24) & 0xFF;
    iv_local[4 + 1] = (engine_time  >> 16) & 0xFF;
    iv_local[4 + 2] = (engine_time  >>  8) & 0xFF;
    iv_local[4 + 3] = (engine_time  >>  0) & 0xFF;
    SMEMCPY(iv_local + 8, priv_param, 8);
    if (mbedtls_cipher_set_iv(&ctx, iv_local, LWIP_ARRAYSIZE(iv_local)) != 0) {
      goto error;
    }

    for (i = 0; i < length; i++) {
      u8_t in_byte;
      u8_t out_byte;
      size_t out_len = sizeof(out_byte);

      if (snmp_pbuf_stream_read(&read_stream, &in_byte) != ERR_OK) {
        goto error;
      }
      if (mbedtls_cipher_update(&ctx, &in_byte, sizeof(in_byte), &out_byte, &out_len) != 0) {
        goto error;
      }
      if (snmp_pbuf_stream_write(&write_stream, out_byte) != ERR_OK) {
        goto error;
      }
    }
  } else {
    return ERR_ARG;
  }

  mbedtls_cipher_free(&ctx);
  return ERR_OK;

error:
  mbedtls_cipher_free(&ctx);
  return ERR_OK;
}

#endif /* LWIP_SNMP_V3_CRYPTO */

/* A.2.1. Password to Key Sample Code for MD5 */
void
snmpv3_password_to_key_md5(
  const u8_t *password,    /* IN */
  size_t      passwordlen, /* IN */
  const u8_t *engineID,    /* IN  - pointer to snmpEngineID  */
  u8_t        engineLength,/* IN  - length of snmpEngineID */
  u8_t       *key)         /* OUT - pointer to caller 16-octet buffer */
{
  mbedtls_md5_context MD;
  u8_t *cp, password_buf[64];
  u32_t password_index = 0;
  u8_t i;
  u32_t count = 0;

  mbedtls_md5_init(&MD); /* initialize MD5 */
  mbedtls_md5_starts(&MD);

  /**********************************************/
  /* Use while loop until we've done 1 Megabyte */
  /**********************************************/
  while (count < 1048576) {
    cp = password_buf;
    for (i = 0; i < 64; i++) {
      /*************************************************/
      /* Take the next octet of the password, wrapping */
      /* to the beginning of the password as necessary.*/
      /*************************************************/
      *cp++ = password[password_index++ % passwordlen];
    }
    mbedtls_md5_update(&MD, password_buf, 64);
    count += 64;
  }
  mbedtls_md5_finish(&MD, key); /* tell MD5 we're done */

  /*****************************************************/
  /* Now localize the key with the engineID and pass   */
  /* through MD5 to produce final key                  */
  /* May want to ensure that engineLength <= 32,       */
  /* otherwise need to use a buffer larger than 64     */
  /*****************************************************/
  SMEMCPY(password_buf, key, 16);
  MEMCPY(password_buf + 16, engineID, engineLength);
  SMEMCPY(password_buf + 16 + engineLength, key, 16);

  mbedtls_md5_starts(&MD);
  mbedtls_md5_update(&MD, password_buf, 32 + engineLength);
  mbedtls_md5_finish(&MD, key);

  mbedtls_md5_free(&MD);
  return;
}

/* A.2.2. Password to Key Sample Code for SHA */
void
snmpv3_password_to_key_sha(
  const u8_t *password,    /* IN */
  size_t      passwordlen, /* IN */
  const u8_t *engineID,    /* IN  - pointer to snmpEngineID  */
  u8_t        engineLength,/* IN  - length of snmpEngineID */
  u8_t       *key)         /* OUT - pointer to caller 20-octet buffer */
{
  mbedtls_sha1_context SH;
  u8_t *cp, password_buf[72];
  u32_t password_index = 0;
  u8_t i;
  u32_t count = 0;

  mbedtls_sha1_init(&SH); /* initialize SHA */
  mbedtls_sha1_starts(&SH);

  /**********************************************/
  /* Use while loop until we've done 1 Megabyte */
  /**********************************************/
  while (count < 1048576) {
    cp = password_buf;
    for (i = 0; i < 64; i++) {
      /*************************************************/
      /* Take the next octet of the password, wrapping */
      /* to the beginning of the password as necessary.*/
      /*************************************************/
      *cp++ = password[password_index++ % passwordlen];
    }
    mbedtls_sha1_update(&SH, password_buf, 64);
    count += 64;
  }
  mbedtls_sha1_finish(&SH, key); /* tell SHA we're done */

  /*****************************************************/
  /* Now localize the key with the engineID and pass   */
  /* through SHA to produce final key                  */
  /* May want to ensure that engineLength <= 32,       */
  /* otherwise need to use a buffer larger than 72     */
  /*****************************************************/
  SMEMCPY(password_buf, key, 20);
  MEMCPY(password_buf + 20, engineID, engineLength);
  SMEMCPY(password_buf + 20 + engineLength, key, 20);

  mbedtls_sha1_starts(&SH);
  mbedtls_sha1_update(&SH, password_buf, 40 + engineLength);
  mbedtls_sha1_finish(&SH, key);

  mbedtls_sha1_free(&SH);
  return;
}

#endif /* LWIP_SNMP && LWIP_SNMP_V3 && LWIP_SNMP_V3_MBEDTLS */
