chiark / gitweb /
Multiarch: Move .so's to triplet paths, and declare M-A: same.
[chiark-tcl.git] / crypto / algtables.c
index 772998685653abca1dff7c11db107b66e8915e0b..e0d6cc8bb3fddb2bc75f6e4bb288e6eba873907b 100644 (file)
 /*
+ * 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/>.
  */
 
-#include <stdint.h>
-#include <netinet/in.h>
 
-#include "hbytes.h"
-#include "serpent.h"
-#include "sha1.h"
-#include "md5.h"
+#include "chiark_tcl_crypto.h"
 
-static void alg_serpent_b_byteswap_block(Byte *b) {
-  uint32_t t, *a= (void*)b;
+#include <nettle/md5.h>
+#include <nettle/sha.h>
+#include <nettle/serpent.h>
+#include <nettle/twofish.h>
+#include <nettle/aes.h>
+#include <nettle/blowfish.h>
 
-  t=    htonl(a[0]);
-  a[0]= htonl(a[3]);
-  a[3]= t;
+#define NETTLE_BLOCKCIPHERS                    \
+  DO(serpent,  SERPENT)                                \
+  DO(twofish,  TWOFISH)                                \
+/* DO(aes,      AES) */                                \
+  DO(blowfish, BLOWFISH)                       \
+  /*  ALIAS(rijndael, aes, AES)*/
 
-  t=    htonl(a[1]);
-  a[1]= htonl(a[2]);
-  a[2]= t;
-}
-
-static void alg_serpent_l_byteswap_block(Byte *b) {
-  uint32_t t, *a= (void*)b;
-  int i;
-
-  if (htonl(0x01020304UL) == 0x04030201UL) /* little endian */
-    return;
-  
-  for (i=0; i<4; i++) {
-    t= htonl(a[i]);
-    a[i]= ((t & 0x000000ffUL) << 24 |
-          (t & 0x0000ff00UL) << 8 |
-          (t & 0x00ff0000UL) >> 8 |
-          (t & 0xff000000UL) >> 24);
+#define ALIAS(alias,name,NAME)
+#define DO(name,NAME)                                                        \
+  static void alg_##name##_makekey(void *sch, const void *key, int keylen) {  \
+    name##_set_key(sch, keylen, key);                                        \
+  }                                                                          \
+  static void alg_##name##_encr(const void *sch, const void *in, void *out) { \
+    name##_encrypt((void*)sch, NAME##_BLOCK_SIZE, out, in);                  \
+  }                                                                          \
+  static void alg_##name##_decr(const void *sch, const void *in, void *out) { \
+    name##_decrypt((void*)sch, NAME##_BLOCK_SIZE, out, in);                  \
   }
-}
-
-static void alg_serpent_makekey(void *schedule, const Byte *key, int keylen) {
-  serpent_makekey(schedule, keylen*8, key);
-}
+  NETTLE_BLOCKCIPHERS
+#undef DO
+#undef ALIAS
 
-static void alg_serpent_encrypt(const void *sch, const void *in, void *out) {
-  serpent_encrypt(sch, in, out);
-}
-  
-static void alg_serpent_decrypt(const void *sch, const void *in, void *out) {
-  serpent_decrypt(sch, in, out);
-}
+const BlockCipherAlgInfo cht_blockcipheralginfo_entries[]= {
+#define ALIAS(alias,name,NAME)                                 \
+  { #alias, NAME##_BLOCK_SIZE, sizeof(struct name##_ctx),      \
+       NAME##_MIN_KEY_SIZE, NAME##_MAX_KEY_SIZE,               \
+    { alg_##name##_makekey, alg_##name##_encr },               \
+    { alg_##name##_makekey, alg_##name##_decr }                        \
+  },
+#define DO(name,NAME) ALIAS(name,name,NAME)
+  NETTLE_BLOCKCIPHERS
+#undef DO
+#undef ALIAS
+  { 0 }
+};
 
-const BlockCipherAlgInfo blockcipheralginfos[]= {
-  { "serpent-l", 16, sizeof(struct SerpentKeyInstance), 16,32,
-    alg_serpent_l_byteswap_block,
-    { alg_serpent_makekey, alg_serpent_encrypt },
-    { alg_serpent_makekey, alg_serpent_decrypt } },
-  { "serpent-b", 16, sizeof(struct SerpentKeyInstance), 16,32,
-    alg_serpent_b_byteswap_block,
-    { alg_serpent_makekey, alg_serpent_encrypt },
-    { alg_serpent_makekey, alg_serpent_decrypt } },
+const BlockCipherPropInfo cht_blockcipherpropinfo_entries[]= {
+  { "blocklen",  offsetof(BlockCipherAlgInfo, blocksize) },
+  { "minkeylen", offsetof(BlockCipherAlgInfo, key_min)   },
+  { "maxkeylen", offsetof(BlockCipherAlgInfo, key_max)   },
   { 0 }
 };
 
-static void alg_sha1_init(void *state) { sha1_init(state); }
-static void alg_sha1_update(void *state, const Byte *data, int len) {
-  sha1_update(state, data, len);
-}
-static void alg_sha1_final(void *state, Byte *digest) {
-  sha1_final(state, digest);
-}
-static void alg_sha1_oneshot(Byte *digest, const Byte *data, int len) {
-  sha1(data,len,digest);
-}
+#define NETTLE_DIGESTS                         \
+  DO(sha1,   SHA1)                             \
+  DO(sha256, SHA256)                           \
+  DO(md5,    MD5)
 
-static void alg_md5_init(void *state) { MD5Init(state); }
-static void alg_md5_update(void *state, const Byte *data, int len) {
-  MD5Update(state, data, len);
-}
-static void alg_md5_final(void *state, Byte *digest) {
-  MD5Final(digest, state);
-}
-static void alg_md5_oneshot(Byte *digest, const Byte *data, int len) {
-  struct MD5Context ctx;
-  MD5Init(&ctx);
-  MD5Update(&ctx,data,len);
-  MD5Final(digest,&ctx);
-}
+#define DO(name,NAME)                                                        \
+  static void alg_##name##_init(void *state) {                               \
+    name##_init(state);                                                              \
+  }                                                                          \
+  static void alg_##name##_update(void *state, const void *data, int len) {   \
+    name##_update(state, len, data);                                         \
+  }                                                                          \
+  static void alg_##name##_final(void *state, void *digest) {                \
+    name##_digest(state,NAME##_DIGEST_SIZE,digest);                          \
+  }                                                                          \
+  static void alg_##name##_oneshot(void *digest, const void *data, int len) { \
+    struct name##_ctx ctx;                                                   \
+    name##_init(&ctx);                                                       \
+    name##_update(&ctx, len, data);                                          \
+    name##_digest(&ctx,NAME##_DIGEST_SIZE,digest);                           \
+  }
+  NETTLE_DIGESTS
+#undef DO
+
+const HashAlgPropInfo cht_hashalgpropinfo_entries[]= {
+  { "hashlen",  offsetof(HashAlgInfo, hashsize)  },
+  { "blocklen", offsetof(HashAlgInfo, blocksize) },
+  { 0 }
+};
 
-const HashAlgInfo hashalginfos[]= {
-  { "sha1", 20, 64, sizeof(struct sha1_state),
-    alg_sha1_init, alg_sha1_update, alg_sha1_final, alg_sha1_oneshot },
-  { "md5", 16, 64, sizeof(struct MD5Context),
-    alg_md5_init, alg_md5_update, alg_md5_final, alg_md5_oneshot },
+const HashAlgInfo cht_hashalginfo_entries[]= {
+#define DO(name,NAME)                                                      \
+  { #name, NAME##_DIGEST_SIZE, NAME##_DATA_SIZE, sizeof(struct name##_ctx), \
+    alg_##name##_init, alg_##name##_update, alg_##name##_final,                    \
+    alg_##name##_oneshot },
+  NETTLE_DIGESTS
+#undef DO
   { 0 }
 };