diff options
author | Luo Jinghua <sunmoon1997@gmail.com> | 2009-11-08 21:59:28 +0800 |
---|---|---|
committer | Luo Jinghua <sunmoon1997@gmail.com> | 2009-11-08 21:59:28 +0800 |
commit | d3e423430a8db14c8cf3583051c0f23241a8df21 (patch) | |
tree | 10275ebeebb56cc15ddaf10470bcc04012bc8762 | |
parent | 6acb8b8c8c928b63840a79738a4c83db55e055b4 (diff) |
milkway: initial implementation of encrypt/decrypt functionality
-rw-r--r-- | milkway/mw-crypt.c | 148 | ||||
-rw-r--r-- | milkway/mw-crypt.h | 7 |
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 |