summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuo Jinghua <sunmoon1997@gmail.com>2009-11-08 21:59:28 +0800
committerLuo Jinghua <sunmoon1997@gmail.com>2009-11-08 21:59:28 +0800
commitd3e423430a8db14c8cf3583051c0f23241a8df21 (patch)
tree10275ebeebb56cc15ddaf10470bcc04012bc8762
parent6acb8b8c8c928b63840a79738a4c83db55e055b4 (diff)
milkway: initial implementation of encrypt/decrypt functionality
-rw-r--r--milkway/mw-crypt.c148
-rw-r--r--milkway/mw-crypt.h7
2 files changed, 146 insertions, 9 deletions
diff --git a/milkway/mw-crypt.c b/milkway/mw-crypt.c
index 7fb0df7..d1e6f86 100644
--- a/milkway/mw-crypt.c
+++ b/milkway/mw-crypt.c
@@ -20,27 +20,165 @@
#include "milkway/mw-crypt.h"
#include "blowfish.h"
+#include "base32.h"
+
+#include <stdio.h>
+
+static char
+mw_crypto_magic[16] = "pp_!#$encrypt";
+static unsigned char
+mw_crypto_blowfish_key[8] = "\x01\x02\x03\x2d\x43\x59\x00\x03";
+
+#define MW_CRYPTO_MAGIC mw_crypto_magic
+#define MW_CRYPTO_MAGIC_LEN sizeof(mw_crypto_magic)
+#define MW_CRYPTO_BLOWFISH_KEY mw_crypto_blowfish_key
+#define MW_CRYPTO_HEADER_SIZE 38
+
+/**
+ * crypted data structure
+ *
+ * Magic:
+ * 16 bytes: pps!#$encrypt\0\0\0
+ * Checksum:
+ * 16 bytes: md5 digest of origin data
+ * LSB Size:
+ * 1 bytes: LSB of origin data size
+ * Size:
+ * 4 bytes(in little endia): encoded data size
+ * Encoding mode:
+ * 1: blowfish where key = \x01\x02\x03\x2d\x43\x59\x00\x03
+ * 2: base32
+ *
+ */
+
int
mw_encrypt(const char *in, size_t inlen,
char *out, size_t *outlen,
int mode)
{
+ const char *s = in;
+ char *cur = out;
+ mw_checksum_t *checksum;
+ size_t encoded_size;
+
if (mode != MW_ENCRYPT_BLOWFISH &&
mode != MW_ENCRYPT_BASE32)
return MW_INVALID;
+ if (*outlen < MW_CRYPTO_HEADER_SIZE)
+ return MW_TOO_SMALL;
+
+ memcpy(cur, MW_CRYPTO_MAGIC, MW_CRYPTO_MAGIC_LEN);
+ cur += 16;
+
+ checksum = mw_checksum_new(MW_CHECKSUM_MD5);
+ mw_checksum_update(checksum, in, inlen);
+ mw_checksum_get_digest(checksum, cur, 16);
+ mw_checksum_destroy(checksum);
+ cur += 16;
+
+ *cur++ = inlen & 0xff;
+ *cur++ = mode;
+
+ encoded_size = inlen;
+ cur[0] = (encoded_size & 0x000000ff) >> 0;
+ cur[1] = (encoded_size & 0x0000ff00) >> 8;
+ cur[2] = (encoded_size & 0x00ff0000) >> 16;
+ cur[3] = (encoded_size & 0xff000000) >> 24;
+ cur += 4;
+
+ if (mode == MW_ENCRYPT_BLOWFISH) {
+ BlowfishContext ctx;
+
+ BlowfishInit(&ctx, MW_CRYPTO_BLOWFISH_KEY,
+ sizeof(MW_CRYPTO_BLOWFISH_KEY));
+ while (s < in + MW_CRYPTO_HEADER_SIZE + encoded_size) {
+ if (s < in + inlen) {
+ BlowfishEcbEncrypt(&ctx, (const unsigned char*)s,
+ (unsigned char*)cur);
+ s += 8;
+ out += 8;
+ } else {
+ size_t left = in + inlen - s;
+
+ memcpy(cur, s, left);
+ s += left;
+ cur += left;
+ }
+ }
+ } else {
+ mw_base32_encode(s, encoded_size, out, *outlen);
+ }
+
return MW_SUCCESS;
}
int
mw_decrypt(const char *in, size_t inlen,
- char *out, size_t outlen,
- int mode)
+ char *out, size_t outlen)
{
- if (mode != MW_ENCRYPT_BLOWFISH &&
- mode != MW_ENCRYPT_BASE32)
+ const char *s = in;
+ const char *checksum;
+ const char *magic;
+ unsigned char lsb_size;
+ char mode;
+ size_t encoded_size;
+
+ if (inlen < MW_CRYPTO_HEADER_SIZE)
+ return MW_TOO_SMALL;
+
+ magic = s;
+ if (memcmp(magic, MW_CRYPTO_MAGIC, MW_CRYPTO_MAGIC_LEN))
return MW_INVALID;
+ s += 16;
- return MW_SUCCESS;
+ checksum = s;
+ s += 16;
+
+ lsb_size = s[0];
+ s++;
+
+ mode = s[0];
+ s++;
+
+ if (mode != 1 && mode != 2)
+ return MW_INVALID;
+
+ encoded_size =
+ (((unsigned char)s[0]) << 0) |
+ (((unsigned char)s[1]) << 8) |
+ (((unsigned char)s[2]) << 16) |
+ (((unsigned char)s[3]) << 24);
+ s += 4;
+
+ if (outlen < encoded_size)
+ return MW_TOO_SMALL;
+ if (inlen - MW_CRYPTO_HEADER_SIZE < encoded_size)
+ return MW_TOO_SMALL;
+
+ if (mode == 1) {
+ BlowfishContext ctx;
+
+ BlowfishInit(&ctx, MW_CRYPTO_BLOWFISH_KEY,
+ sizeof(MW_CRYPTO_BLOWFISH_KEY));
+ while (s < in + MW_CRYPTO_HEADER_SIZE + encoded_size) {
+ if (s + 8 < in + inlen) {
+ BlowfishEcbDecrypt(&ctx, (const unsigned char*)s,
+ (unsigned char*)out);
+ s += 8;
+ out += 8;
+ } else {
+ size_t left = in + inlen - s;
+
+ memcpy(out, s, left);
+ s += left;
+ out += left;
+ }
+ }
+ } else {
+ mw_base32_decode(s, encoded_size, out, &outlen);
+ }
+
+ return encoded_size;
}
diff --git a/milkway/mw-crypt.h b/milkway/mw-crypt.h
index 6e6cda9..64cee74 100644
--- a/milkway/mw-crypt.h
+++ b/milkway/mw-crypt.h
@@ -22,14 +22,13 @@ enum mw_crypt_mode {
MW_ENCRYPT_BASE32
};
-int
+mw_public int
mw_encrypt(const char *in, size_t inlen,
char *out, size_t *outlen,
int mode);
-int
+mw_public int
mw_decrypt(const char *in, size_t inlen,
- char *out, size_t outlen,
- int mode);
+ char *out, size_t outlen);
#endif