/*
 * crypto - Tcl bindings for parts of the `nettle' crypto library
 * Copyright 2006-2012 Ian Jackson
 *
 * 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 of the
 * License, 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 library; if not, see <http://www.gnu.org/licenses/>.
 */


#ifndef CRYPTO_H
#define CRYPTO_H

#include "chiark-tcl.h"

/* from crypto.c */

void memxor(Byte *dest, const Byte *src, int l);

typedef struct {
  const char *name;
  int pad, use_algname;
} PadOp;

extern Tcl_ObjType cht_blockcipherkey_type;

/* from algtables.c */

typedef struct {
  const char *name;
  int int_offset;
} BlockCipherPropInfo, HashAlgPropInfo;

typedef struct {
  const char *name;
  int hashsize, blocksize, statesize;
  void (*init)(void *state);
  void (*update)(void *state, const void *data, int len);
  void (*final)(void *state, void *digest);
  void (*oneshot)(void *digest, const void *data, int len);
} HashAlgInfo;

extern const HashAlgInfo cht_hashalginfo_entries[];

typedef struct {
  void (*make_schedule)(void *schedule, const void *key, int keylen);
  void (*crypt)(const void *schedule, const void *in, void *out);
     /* in and out may be the same, but if they aren't they may not overlap */
     /* in and out for crypt will have been through block_byteswap */
} BlockCipherPerDirectionInfo;

typedef struct {
  const char *name;
  int blocksize, schedule_size, key_min, key_max;
  BlockCipherPerDirectionInfo encrypt, decrypt;
} BlockCipherAlgInfo;

extern const BlockCipherAlgInfo cht_blockcipheralginfo_entries[];

/* from bcmode.c */

typedef struct {
  const char *name;
  int iv_blocks, buf_blocks, mac_blocks;

  /* Each function is allowed to use up to buf_blocks * blocksize
   * bytes of space in buf.  data is blocks * blocksize bytes
   * long.  data should be modified in place by encrypt and decrypt;
   * modes may not change the size of data.  iv is always provided and
   * is always of length iv_blocks * blocksize; encrypt and
   * decrypt may modify the iv value (in which case the Tcl caller
   * will get the modified IV) but this is not recommended.  mac
   * should leave the mac, which must be mac_blocks * blocksize
   * bytes, in buf.  (Therefore mac_blocks must be at least
   * buf_blocks.)
   */
  const char *(*encrypt)(Byte *data, int nblocks,
			 const Byte *iv, Byte *buf,
			 const BlockCipherAlgInfo *alg, int encr,
			 const void *sch);
  const char *(*decrypt)(Byte *data, int nblocks,
			 const Byte *iv, Byte *buf,
			 const BlockCipherAlgInfo *alg, int encr,
			 const void *sch);
  const char *(*mac)(const Byte *data, int nblocks,
		     const Byte *iv, Byte *buf,
		     const BlockCipherAlgInfo *alg,
		     const void *sch);
} BlockCipherModeInfo;

extern const IdDataSpec cht_hash_states;
extern const BlockCipherModeInfo cht_blockciphermodeinfo_entries[];

#include "crypto+tcmdif.h"

#endif /*CRYPTO_H*/
