[Dovecot] [PATCH, RFC 1/13] OTP: hash generation
Andrey Panin
pazke at donpac.ru
Mon Jun 26 15:57:57 EEST 2006
Add OTP hash generation functions.
diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/lib-otp/otp-hash.c dovecot/src/lib-otp/otp-hash.c
--- dovecot.vanilla/src/lib-otp/otp-hash.c 1970-01-01 03:00:00.000000000 +0300
+++ dovecot/src/lib-otp/otp-hash.c 2006-06-23 13:44:31.011913912 +0400
@@ -0,0 +1,163 @@
+/*
+ * OTP hash generaion.
+ *
+ * Copyright (c) 2006 Andrey Panin <pazke at donpac.ru>
+ *
+ * This software is released under the MIT license.
+ */
+
+#include "lib.h"
+#include "md4.h"
+#include "md5.h"
+#include "sha1.h"
+
+#include "otp.h"
+
+struct digest {
+ const char *name;
+ void (*init)(void *ctx);
+ void (*update)(void *ctx, const void *data, const size_t size);
+ void (*final)(void *ctx, void *res);
+ void (*otp_final)(void *ctx, void *res);
+};
+
+struct digest_context {
+ struct digest *digest;
+ union {
+ struct md4_context md4_ctx;
+ struct md5_context md5_ctx;
+ struct sha1_ctxt sha1_ctx;
+ } ctx;
+};
+
+static void md4_fold(struct md4_context *ctx, void *res)
+{
+ uint32_t tmp[4], *p = res;
+
+ md4_final(ctx, (unsigned char *) tmp);
+
+ *p++ = tmp[0] ^ tmp[2];
+ *p = tmp[1] ^ tmp[3];
+}
+
+static void md5_fold(struct md5_context *ctx, void *res)
+{
+ uint32_t tmp[4], *p = res;
+
+ md5_final(ctx, (unsigned char *) tmp);
+
+ *p++ = tmp[0] ^ tmp[2];
+ *p = tmp[1] ^ tmp[3];
+}
+
+/*
+ * Sometimes I simply can't look at code generated by gcc.
+ */
+static inline uint32_t swab(uint32_t val)
+{
+#if defined(__GNUC__) && defined(__i386__)
+ asm("xchgb %b0, %h0\n"
+ "rorl $16, %0\n"
+ "xchgb %b0, %h0\n"
+ :"=q" (val)
+ : "0" (val));
+#else
+ val = ((val & 0xff) << 24) | ((val & 0xff00) << 8) |
+ ((val & 0xff0000) >> 8) | ((val >> 24) & 0xff);
+#endif
+ return val;
+}
+
+static void sha1_fold(struct sha1_ctxt *ctx, void *res)
+{
+ uint32_t tmp[5], *p = res;
+
+ sha1_result(ctx, tmp);
+
+ *p++ = swab(tmp[0] ^ tmp[2] ^ tmp[4]);
+ *p = swab(tmp[1] ^ tmp[3]);
+}
+
+
+#define F(name) ((void *) (name))
+
+static struct digest digests[] = {
+ { "md4", F(md4_init), F(md4_update), F(md4_final), F(md4_fold) },
+ { "md5", F(md5_init), F(md5_update), F(md5_final), F(md5_fold) },
+ { "sha1", F(sha1_init), F(sha1_loop), F(sha1_result), F(sha1_fold) },
+};
+
+#define N_DIGESTS (int)(sizeof(digests) / sizeof(digests[0]))
+
+#undef F
+
+const char * digest_name(int algo)
+{
+ return (algo < N_DIGESTS) ? digests[algo].name : NULL;
+}
+
+int digest_find(const char *name)
+{
+ int i;
+
+ for (i = 0; i < N_DIGESTS; i++)
+ if (strcmp(name, digests[i].name) == 0)
+ return i;
+
+ return -1;
+}
+
+int digest_init(struct digest_context *ctx, const int algo)
+{
+ i_assert(algo >= 0);
+
+ ctx->digest = digests + algo;
+
+ ctx->digest->init((void *) &ctx->ctx);
+
+ return 0;
+}
+
+void digest_update(struct digest_context *ctx, const void *data,
+ const size_t size)
+{
+ ctx->digest->update((void *) &ctx->ctx, data, size);
+}
+
+void digest_final(struct digest_context *ctx, unsigned char *result)
+{
+ ctx->digest->final((void *) &ctx->ctx, result);
+}
+
+void digest_otp_final(struct digest_context *ctx, unsigned char *result)
+{
+ ctx->digest->otp_final((void *) &ctx->ctx, result);
+}
+
+
+void otp_hash(int algo, const char *seed, const char *passphrase,
+ int step, unsigned char *result)
+{
+ struct digest_context ctx;
+
+ digest_init(&ctx, algo);
+ digest_update(&ctx, seed, strlen(seed));
+ digest_update(&ctx, passphrase, strlen(passphrase));
+ digest_otp_final(&ctx, result);
+
+ while (step--) {
+ digest_init(&ctx, algo);
+ digest_update(&ctx, result, OTP_HASH_SIZE);
+ digest_otp_final(&ctx, result);
+ }
+}
+
+void otp_next_hash(int algo, const unsigned char *prev,
+ unsigned char *result)
+{
+ struct digest_context ctx;
+
+ digest_init(&ctx, algo);
+ digest_update(&ctx, prev, OTP_HASH_SIZE);
+ digest_otp_final(&ctx, result);
+}
diff -urdpNX /usr/share/dontdiff -x Makefile dovecot.vanilla/src/lib-otp/otp-hash.h dovecot/src/lib-otp/otp-hash.h
--- dovecot.vanilla/src/lib-otp/otp-hash.h 1970-01-01 03:00:00.000000000 +0300
+++ dovecot/src/lib-otp/otp-hash.h 2006-06-23 13:44:31.011913912 +0400
@@ -0,0 +1,25 @@
+#ifndef __OTP_HASH_H__
+#define __OTP_HASH_H__
+
+struct digest_context;
+
+enum {
+ OTP_HASH_MD4,
+ OTP_HASH_MD5,
+ OTP_HASH_SHA1,
+};
+
+int digest_find(const char *name);
+int digest_init(struct digest_context *ctx, const int algo);
+void digest_update(struct digest_context *ctx, const void *data,
+ const size_t size);
+void digest_final(struct digest_context *ctx, unsigned char *result);
+void digest_otp_final(struct digest_context *ctx, unsigned char *result);
+const char * digest_name(int algo);
+
+void otp_hash(int algo, const char *seed, const char *passphrase,
+ int step, unsigned char *result);
+
+void otp_next_hash(int algo, const unsigned char *prev, unsigned char *result);
+
+#endif /* __OTP_HASH_H__ */
More information about the dovecot
mailing list