summaryrefslogtreecommitdiff
path: root/plugins/MirOTR/Libgcrypt/cipher/camellia-glue.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/MirOTR/Libgcrypt/cipher/camellia-glue.c')
-rw-r--r--plugins/MirOTR/Libgcrypt/cipher/camellia-glue.c253
1 files changed, 253 insertions, 0 deletions
diff --git a/plugins/MirOTR/Libgcrypt/cipher/camellia-glue.c b/plugins/MirOTR/Libgcrypt/cipher/camellia-glue.c
new file mode 100644
index 0000000000..067af85bca
--- /dev/null
+++ b/plugins/MirOTR/Libgcrypt/cipher/camellia-glue.c
@@ -0,0 +1,253 @@
+/* camellia-glue.c - Glue for the Camellia cipher
+ * Copyright (C) 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser 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.
+ */
+
+/* I put all the libgcrypt-specific stuff in this file to keep the
+ camellia.c/camellia.h files exactly as provided by NTT. If they
+ update their code, this should make it easier to bring the changes
+ in. - dshaw
+
+ There is one small change which needs to be done: Include the
+ following code at the top of camellia.h: */
+#if 0
+
+/* To use Camellia with libraries it is often useful to keep the name
+ * space of the library clean. The following macro is thus useful:
+ *
+ * #define CAMELLIA_EXT_SYM_PREFIX foo_
+ *
+ * This prefixes all external symbols with "foo_".
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifdef CAMELLIA_EXT_SYM_PREFIX
+#define CAMELLIA_PREFIX1(x,y) x ## y
+#define CAMELLIA_PREFIX2(x,y) CAMELLIA_PREFIX1(x,y)
+#define CAMELLIA_PREFIX(x) CAMELLIA_PREFIX2(CAMELLIA_EXT_SYM_PREFIX,x)
+#define Camellia_Ekeygen CAMELLIA_PREFIX(Camellia_Ekeygen)
+#define Camellia_EncryptBlock CAMELLIA_PREFIX(Camellia_EncryptBlock)
+#define Camellia_DecryptBlock CAMELLIA_PREFIX(Camellia_DecryptBlock)
+#define camellia_decrypt128 CAMELLIA_PREFIX(camellia_decrypt128)
+#define camellia_decrypt256 CAMELLIA_PREFIX(camellia_decrypt256)
+#define camellia_encrypt128 CAMELLIA_PREFIX(camellia_encrypt128)
+#define camellia_encrypt256 CAMELLIA_PREFIX(camellia_encrypt256)
+#define camellia_setup128 CAMELLIA_PREFIX(camellia_setup128)
+#define camellia_setup192 CAMELLIA_PREFIX(camellia_setup192)
+#define camellia_setup256 CAMELLIA_PREFIX(camellia_setup256)
+#endif /*CAMELLIA_EXT_SYM_PREFIX*/
+
+#endif /* Code sample. */
+
+
+#include <config.h>
+#include "types.h"
+#include "g10lib.h"
+#include "cipher.h"
+#include "camellia.h"
+
+typedef struct
+{
+ int keybitlength;
+ KEY_TABLE_TYPE keytable;
+} CAMELLIA_context;
+
+static const char *selftest(void);
+
+static gcry_err_code_t
+camellia_setkey(void *c, const byte *key, unsigned keylen)
+{
+ CAMELLIA_context *ctx=c;
+ static int initialized=0;
+ static const char *selftest_failed=NULL;
+
+ if(keylen!=16 && keylen!=24 && keylen!=32)
+ return GPG_ERR_INV_KEYLEN;
+
+ if(!initialized)
+ {
+ initialized=1;
+ selftest_failed=selftest();
+ if(selftest_failed)
+ log_error("%s\n",selftest_failed);
+ }
+
+ if(selftest_failed)
+ return GPG_ERR_SELFTEST_FAILED;
+
+ ctx->keybitlength=keylen*8;
+ Camellia_Ekeygen(ctx->keybitlength,key,ctx->keytable);
+ _gcry_burn_stack
+ ((19+34+34)*sizeof(u32)+2*sizeof(void*) /* camellia_setup256 */
+ +(4+32)*sizeof(u32)+2*sizeof(void*) /* camellia_setup192 */
+ +0+sizeof(int)+2*sizeof(void*) /* Camellia_Ekeygen */
+ +3*2*sizeof(void*) /* Function calls. */
+ );
+
+ return 0;
+}
+
+static void
+camellia_encrypt(void *c, byte *outbuf, const byte *inbuf)
+{
+ CAMELLIA_context *ctx=c;
+
+ Camellia_EncryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
+ _gcry_burn_stack
+ (sizeof(int)+2*sizeof(unsigned char *)+sizeof(KEY_TABLE_TYPE)
+ +4*sizeof(u32)
+ +2*sizeof(u32*)+4*sizeof(u32)
+ +2*2*sizeof(void*) /* Function calls. */
+ );
+}
+
+static void
+camellia_decrypt(void *c, byte *outbuf, const byte *inbuf)
+{
+ CAMELLIA_context *ctx=c;
+
+ Camellia_DecryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
+ _gcry_burn_stack
+ (sizeof(int)+2*sizeof(unsigned char *)+sizeof(KEY_TABLE_TYPE)
+ +4*sizeof(u32)
+ +2*sizeof(u32*)+4*sizeof(u32)
+ +2*2*sizeof(void*) /* Function calls. */
+ );
+}
+
+static const char *
+selftest(void)
+{
+ CAMELLIA_context ctx;
+ byte scratch[16];
+
+ /* These test vectors are from RFC-3713 */
+ const byte plaintext[]=
+ {
+ 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
+ 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
+ };
+ const byte key_128[]=
+ {
+ 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
+ 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
+ };
+ const byte ciphertext_128[]=
+ {
+ 0x67,0x67,0x31,0x38,0x54,0x96,0x69,0x73,
+ 0x08,0x57,0x06,0x56,0x48,0xea,0xbe,0x43
+ };
+ const byte key_192[]=
+ {
+ 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,
+ 0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77
+ };
+ const byte ciphertext_192[]=
+ {
+ 0xb4,0x99,0x34,0x01,0xb3,0xe9,0x96,0xf8,
+ 0x4e,0xe5,0xce,0xe7,0xd7,0x9b,0x09,0xb9
+ };
+ const byte key_256[]=
+ {
+ 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,
+ 0x98,0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,
+ 0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff
+ };
+ const byte ciphertext_256[]=
+ {
+ 0x9a,0xcc,0x23,0x7d,0xff,0x16,0xd7,0x6c,
+ 0x20,0xef,0x7c,0x91,0x9e,0x3a,0x75,0x09
+ };
+
+ camellia_setkey(&ctx,key_128,sizeof(key_128));
+ camellia_encrypt(&ctx,scratch,plaintext);
+ if(memcmp(scratch,ciphertext_128,sizeof(ciphertext_128))!=0)
+ return "CAMELLIA-128 test encryption failed.";
+ camellia_decrypt(&ctx,scratch,scratch);
+ if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
+ return "CAMELLIA-128 test decryption failed.";
+
+ camellia_setkey(&ctx,key_192,sizeof(key_192));
+ camellia_encrypt(&ctx,scratch,plaintext);
+ if(memcmp(scratch,ciphertext_192,sizeof(ciphertext_192))!=0)
+ return "CAMELLIA-192 test encryption failed.";
+ camellia_decrypt(&ctx,scratch,scratch);
+ if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
+ return "CAMELLIA-192 test decryption failed.";
+
+ camellia_setkey(&ctx,key_256,sizeof(key_256));
+ camellia_encrypt(&ctx,scratch,plaintext);
+ if(memcmp(scratch,ciphertext_256,sizeof(ciphertext_256))!=0)
+ return "CAMELLIA-256 test encryption failed.";
+ camellia_decrypt(&ctx,scratch,scratch);
+ if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
+ return "CAMELLIA-256 test decryption failed.";
+
+ return NULL;
+}
+
+/* These oids are from
+ <http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications_oid.html>,
+ retrieved May 1, 2007. */
+
+static gcry_cipher_oid_spec_t camellia128_oids[] =
+ {
+ {"1.2.392.200011.61.1.1.1.2", GCRY_CIPHER_MODE_CBC},
+ {"0.3.4401.5.3.1.9.1", GCRY_CIPHER_MODE_ECB},
+ {"0.3.4401.5.3.1.9.3", GCRY_CIPHER_MODE_OFB},
+ {"0.3.4401.5.3.1.9.4", GCRY_CIPHER_MODE_CFB},
+ { NULL }
+ };
+
+static gcry_cipher_oid_spec_t camellia192_oids[] =
+ {
+ {"1.2.392.200011.61.1.1.1.3", GCRY_CIPHER_MODE_CBC},
+ {"0.3.4401.5.3.1.9.21", GCRY_CIPHER_MODE_ECB},
+ {"0.3.4401.5.3.1.9.23", GCRY_CIPHER_MODE_OFB},
+ {"0.3.4401.5.3.1.9.24", GCRY_CIPHER_MODE_CFB},
+ { NULL }
+ };
+
+static gcry_cipher_oid_spec_t camellia256_oids[] =
+ {
+ {"1.2.392.200011.61.1.1.1.4", GCRY_CIPHER_MODE_CBC},
+ {"0.3.4401.5.3.1.9.41", GCRY_CIPHER_MODE_ECB},
+ {"0.3.4401.5.3.1.9.43", GCRY_CIPHER_MODE_OFB},
+ {"0.3.4401.5.3.1.9.44", GCRY_CIPHER_MODE_CFB},
+ { NULL }
+ };
+
+gcry_cipher_spec_t _gcry_cipher_spec_camellia128 =
+ {
+ "CAMELLIA128",NULL,camellia128_oids,CAMELLIA_BLOCK_SIZE,128,
+ sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
+ };
+
+gcry_cipher_spec_t _gcry_cipher_spec_camellia192 =
+ {
+ "CAMELLIA192",NULL,camellia192_oids,CAMELLIA_BLOCK_SIZE,192,
+ sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
+ };
+
+gcry_cipher_spec_t _gcry_cipher_spec_camellia256 =
+ {
+ "CAMELLIA256",NULL,camellia256_oids,CAMELLIA_BLOCK_SIZE,256,
+ sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
+ };