/*
  Copyright (C) 2003-2010 FreeIPMI Core Team

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2, or (at your option)
  any later version.

  This program 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 General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software Foundation,
  Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
*/

#ifndef _IPMI_CRYPT_H
#define _IPMI_CRYPT_H

#include <stdint.h>

#define IPMI_CRYPT_HASH_SHA1             0x00
#define IPMI_CRYPT_HASH_MD5              0x01

#define IPMI_CRYPT_HASH_ALGORITHM_VALID(__hash_algorithm)       \
  (((__hash_algorithm) == IPMI_CRYPT_HASH_SHA1                  \
    || (__hash_algorithm) == IPMI_CRYPT_HASH_MD5) ? 1 : 0)

#define IPMI_CRYPT_HASH_FLAGS_HMAC       0x01

#define IPMI_CRYPT_CIPHER_AES            0x00

#define IPMI_CRYPT_CIPHER_ALGORITHM_VALID(__cipher_algorithm)   \
  (((__cipher_algorithm) == IPMI_CRYPT_CIPHER_AES) ? 1 : 0)

#define IPMI_CRYPT_CIPHER_MODE_NONE      0x00
#define IPMI_CRYPT_CIPHER_MODE_CBC       0x01

#define IPMI_CRYPT_CIPHER_MODE_VALID(__cipher_mode)             \
  (((__cipher_mode) == IPMI_CRYPT_CIPHER_MODE_NONE              \
    || (__cipher_mode) == IPMI_CRYPT_CIPHER_MODE_CBC) ? 1 : 0)

#define IPMI_CRYPT_CIPHER_INFO_KEY_LENGTH   0x00
#define IPMI_CRYPT_CIPHER_INFO_BLOCK_LENGTH 0x01

#define IPMI_CRYPT_CIPHER_INFO_VALID(__cipher_info)                     \
  (((__cipher_info) == IPMI_CRYPT_CIPHER_INFO_KEY_LENGTH                \
    || (__cipher_info) == IPMI_CRYPT_CIPHER_INFO_BLOCK_LENGTH) ? 1 : 0)

#define IPMI_CRYPT_AES_CBC_128_IV_LENGTH         16
#define IPMI_CRYPT_AES_CBC_128_KEY_LENGTH        16
#define IPMI_CRYPT_AES_CBC_128_BLOCK_LENGTH      16

/* ipmi_crypt_init
 *
 * Must be called first before anything else that may use crypt
 * functions.  In threaded programs, must be called before threads are
 * created.
 *
 * Returns 0 on success, -1 on error.
 */
int ipmi_crypt_init (void);

/* return length of data written into buffer on success, -1 on error */
int ipmi_crypt_hash (unsigned int hash_algorithm,
                     unsigned int hash_flags,
                     const void *key,
                     unsigned int key_len,
                     const void *hash_data,
                     unsigned int hash_data_len,
                     void *digest,
                     unsigned int digest_len);

int ipmi_crypt_hash_digest_len (unsigned int hash_algorithm);

/* return length of data written into buffer on success, -1 on error */
int ipmi_crypt_cipher_encrypt (unsigned int cipher_algorithm,
                               unsigned int cipher_mode,
                               const void *key,
                               unsigned int key_len,
                               const void *iv,
                               unsigned int iv_len,
                               void *data,
                               unsigned int data_len);

/* return length of data written into buffer on success, -1 on error */
int ipmi_crypt_cipher_decrypt (unsigned int cipher_algorithm,
                               unsigned int cipher_mode,
                               const void *key,
                               unsigned int key_len,
                               const void *iv,
                               unsigned int iv_len,
                               void *data,
                               unsigned int data_len);

int ipmi_crypt_cipher_key_len (unsigned int cipher_algorithm);

int ipmi_crypt_cipher_block_len (unsigned int cipher_algorithm);

#endif
