diff --git a/include/cryb/aes.h b/include/cryb/aes.h index e1c7167..cf2fc3b 100644 --- a/include/cryb/aes.h +++ b/include/cryb/aes.h @@ -43,7 +43,9 @@ CRYB_BEGIN #define aes_cipher cryb_aes_cipher #define aes_ctx cryb_aes_ctx #define aes_init cryb_aes_init -#define aes_update cryb_aes_update +#define aes_keystream cryb_aes_keystream +#define aes_encrypt cryb_aes_encrypt +#define aes_decrypt cryb_aes_decrypt #define aes_finish cryb_aes_finish extern cipher_algorithm aes128_cipher; @@ -56,8 +58,10 @@ typedef struct { uint32_t rk[68]; } aes_ctx; -void aes_init(aes_ctx *, cipher_mode, const uint8_t *, size_t); -void aes_update(aes_ctx *, const void *, size_t, void *); +void aes_init(aes_ctx *, cipher_mode mode, const uint8_t *, size_t); +size_t aes_keystream(aes_ctx *, uint8_t *, size_t); +size_t aes_encrypt(aes_ctx *, const void *, uint8_t *, size_t); +size_t aes_decrypt(aes_ctx *, const uint8_t *, void *, size_t); void aes_finish(aes_ctx *); CRYB_END diff --git a/include/cryb/cipher.h b/include/cryb/cipher.h index 8289925..eb511ed 100644 --- a/include/cryb/cipher.h +++ b/include/cryb/cipher.h @@ -40,7 +40,9 @@ const char *cryb_cipher_version(void); #define cipher_ctx cryb_cipher_ctx #define cipher_init_func cryb_cipher_init_func -#define cipher_update_func cryb_cipher_update_func +#define cipher_keystream_func cryb_cipher_keystream_func +#define cipher_encrypt_func cryb_cipher_encrypt_func +#define cipher_decrypt_func cryb_cipher_decrypt_func #define cipher_finish_func cryb_cipher_finish_func #define cipher_algorithm cryb_cipher_algorithm @@ -51,7 +53,9 @@ typedef enum { typedef void cipher_ctx; typedef void (*cipher_init_func)(cipher_ctx *, cipher_mode, const uint8_t *, size_t); -typedef void (*cipher_update_func)(cipher_ctx *, const void *, size_t, void *); +typedef void (*cipher_keystream_func)(cipher_ctx *, uint8_t *, size_t); +typedef void (*cipher_encrypt_func)(cipher_ctx *, const void *, uint8_t *, size_t); +typedef void (*cipher_decrypt_func)(cipher_ctx *, const uint8_t *, void *, size_t); typedef void (*cipher_finish_func)(cipher_ctx *); typedef struct { @@ -59,9 +63,11 @@ typedef struct { size_t contextlen; /* size of context structure */ size_t blocklen; /* block length */ size_t keylen; /* key length */ - cipher_init_func init; /* initialization method */ - cipher_update_func update; /* {enc,dec}ryption method */ - cipher_finish_func finish; /* finalization method */ + cipher_init_func init; /* initialize */ + cipher_keystream_func keystream; /* generate keystream */ + cipher_encrypt_func encrypt; /* encrypt */ + cipher_decrypt_func decrypt; /* decrypt */ + cipher_finish_func finish; /* finalize */ } cipher_algorithm; #define get_cipher_algorithm cryb_get_cipher_algorithm @@ -70,8 +76,12 @@ const cipher_algorithm *get_cipher_algorithm(const char *); #define cipher_init(alg, ctx, mode, key, keylen) \ (alg)->init((ctx), (mode), (key), (keylen)) -#define cipher_update(alg, ctx, in, len, out) \ - (alg)->update((ctx), (in), (len), (out)) +#define cipher_keystream(alg, ctx, out, len) \ + (alg)->keystream((ctx), (out), (len)) +#define cipher_encrypt(alg, ctx, in, out, len) \ + (alg)->encrypt((ctx), (in), (out), (len)) +#define cipher_decrypt(alg, ctx, in, out, len) \ + (alg)->decrypt((ctx), (in), (out), (len)) #define cipher_finish(alg, ctx) \ (alg)->finish((ctx)) diff --git a/include/cryb/rc4.h b/include/cryb/rc4.h index 14e2292..e94120e 100644 --- a/include/cryb/rc4.h +++ b/include/cryb/rc4.h @@ -41,7 +41,9 @@ CRYB_BEGIN #define rc4_cipher cryb_rc4_cipher #define rc4_ctx cryb_rc4_ctx #define rc4_init cryb_rc4_init -#define rc4_update cryb_rc4_update +#define rc4_keystream cryb_rc4_keystream +#define rc4_encrypt cryb_rc4_encrypt +#define rc4_decrypt cryb_rc4_decrypt #define rc4_finish cryb_rc4_finish extern cipher_algorithm rc4_cipher; @@ -50,8 +52,10 @@ typedef struct { uint8_t s[256], i, j; } rc4_ctx; -void rc4_init(rc4_ctx *, cipher_mode, const uint8_t *, size_t); -void rc4_update(rc4_ctx *, const void *, size_t, void *); +void rc4_init(rc4_ctx *, cipher_mode mode, const uint8_t *, size_t); +size_t rc4_keystream(rc4_ctx *, uint8_t *, size_t); +size_t rc4_encrypt(rc4_ctx *, const void *, uint8_t *, size_t); +size_t rc4_decrypt(rc4_ctx *, const uint8_t *, void *, size_t); void rc4_finish(rc4_ctx *); CRYB_END diff --git a/lib/cipher/cryb_aes.c b/lib/cipher/cryb_aes.c index c8511b3..2a72472 100644 --- a/lib/cipher/cryb_aes.c +++ b/lib/cipher/cryb_aes.c @@ -597,6 +597,30 @@ aes_update(aes_ctx *ctx, const void *in, size_t len, void *out) aes_enc(ctx, in, out); } +size_t +aes_encrypt(aes_ctx *ctx, const void *vpt, uint8_t *ct, size_t len) +{ + const uint8_t *pt = vpt; + unsigned int i; + + len -= len % AES_BLOCK_LEN; + for (i = 0; i < len; i += AES_BLOCK_LEN) + aes_enc(ctx, pt + i, ct + i); + return (len); +} + +size_t +aes_decrypt(aes_ctx *ctx, const uint8_t *ct, void *vpt, size_t len) +{ + uint8_t *pt = vpt; + unsigned int i; + + len -= len % AES_BLOCK_LEN; + for (i = 0; i < len; i += AES_BLOCK_LEN) + aes_dec(ctx, ct + i, pt + i); + return (len); +} + void aes_finish(aes_ctx *ctx) { @@ -610,7 +634,8 @@ cipher_algorithm aes128_cipher = { .blocklen = AES_BLOCK_LEN, .keylen = 128 / 8, .init = (cipher_init_func)aes_init, - .update = (cipher_update_func)aes_update, + .encrypt = (cipher_encrypt_func)aes_encrypt, + .decrypt = (cipher_decrypt_func)aes_decrypt, .finish = (cipher_finish_func)aes_finish, }; @@ -620,7 +645,8 @@ cipher_algorithm aes192_cipher = { .blocklen = AES_BLOCK_LEN, .keylen = 192 / 8, .init = (cipher_init_func)aes_init, - .update = (cipher_update_func)aes_update, + .encrypt = (cipher_encrypt_func)aes_encrypt, + .decrypt = (cipher_decrypt_func)aes_decrypt, .finish = (cipher_finish_func)aes_finish, }; @@ -630,6 +656,7 @@ cipher_algorithm aes256_cipher = { .blocklen = AES_BLOCK_LEN, .keylen = 256 / 8, .init = (cipher_init_func)aes_init, - .update = (cipher_update_func)aes_update, + .encrypt = (cipher_encrypt_func)aes_encrypt, + .decrypt = (cipher_decrypt_func)aes_decrypt, .finish = (cipher_finish_func)aes_finish, }; diff --git a/lib/cipher/cryb_rc4.c b/lib/cipher/cryb_rc4.c index d50f066..5dc7181 100644 --- a/lib/cipher/cryb_rc4.c +++ b/lib/cipher/cryb_rc4.c @@ -34,6 +34,7 @@ #include #include +#include #include @@ -55,12 +56,30 @@ rc4_init(rc4_ctx *ctx, cipher_mode mode, const uint8_t *key, size_t keylen) } } -void -rc4_update(rc4_ctx *ctx, const void *in, size_t len, void *out) +size_t +rc4_keystream(rc4_ctx *ctx, uint8_t *ks, size_t len) { - const uint8_t *is = in; - uint8_t t, k, *os = out; unsigned int i; + uint8_t t; + + for (i = 0; i < len; ++i) { + ctx->i = ctx->i + 1; + ctx->j = ctx->j + ctx->s[ctx->i]; + t = ctx->s[ctx->i]; + ctx->s[ctx->i] = ctx->s[ctx->j]; + ctx->s[ctx->j] = t; + t = ctx->s[ctx->i] + ctx->s[ctx->j]; + *ks++ = ctx->s[t]; + } + return (len); +} + +size_t +rc4_encrypt(rc4_ctx *ctx, const void *vpt, uint8_t *ct, size_t len) +{ + const uint8_t *pt = vpt; + unsigned int i; + uint8_t t, k; for (i = 0; i < len; ++i) { ctx->i = ctx->i + 1; @@ -70,15 +89,23 @@ rc4_update(rc4_ctx *ctx, const void *in, size_t len, void *out) ctx->s[ctx->j] = t; t = ctx->s[ctx->i] + ctx->s[ctx->j]; k = ctx->s[t]; - *os++ = *is++ ^ k; + *ct++ = *pt++ ^ k; } + return (len); +} + +size_t +rc4_decrypt(rc4_ctx *ctx, const uint8_t *in, void *out, size_t len) +{ + + return (rc4_encrypt(ctx, in, out, len)); } void rc4_finish(rc4_ctx *ctx) { - memset(ctx, 0, sizeof *ctx); + memset_s(ctx, 0, sizeof *ctx, sizeof *ctx); } cipher_algorithm rc4_cipher = { @@ -87,6 +114,8 @@ cipher_algorithm rc4_cipher = { .blocklen = 1, .keylen = 0, .init = (cipher_init_func)rc4_init, - .update = (cipher_update_func)rc4_update, + .keystream = (cipher_keystream_func)rc4_keystream, + .encrypt = (cipher_encrypt_func)rc4_encrypt, + .decrypt = (cipher_decrypt_func)rc4_decrypt, .finish = (cipher_finish_func)rc4_finish, }; diff --git a/t/t_aes.c b/t/t_aes.c index b64934b..2ba4f8d 100644 --- a/t/t_aes.c +++ b/t/t_aes.c @@ -113,12 +113,16 @@ t_aes_enc(char **desc, void *arg) struct t_case *t = arg; uint8_t out[AES_BLOCK_LEN]; aes_ctx ctx; + size_t len; + int ret; (void)asprintf(desc, "%s (encrypt)", t->desc); aes_init(&ctx, CIPHER_MODE_ENCRYPT, t->key, t->keylen / 8); - aes_update(&ctx, t->ptext, AES_BLOCK_LEN, out); + len = aes_encrypt(&ctx, t->ptext, out, AES_BLOCK_LEN); aes_finish(&ctx); - return (t_compare_mem(t->ctext, out, AES_BLOCK_LEN)); + ret = t_compare_sz(AES_BLOCK_LEN, len) & + t_compare_mem(t->ctext, out, AES_BLOCK_LEN); + return (ret); } static int @@ -127,12 +131,16 @@ t_aes_dec(char **desc, void *arg) struct t_case *t = arg; uint8_t out[AES_BLOCK_LEN]; aes_ctx ctx; + size_t len; + int ret; (void)asprintf(desc, "%s (decrypt)", t->desc); aes_init(&ctx, CIPHER_MODE_DECRYPT, t->key, t->keylen / 8); - aes_update(&ctx, t->ctext, AES_BLOCK_LEN, out); + len = aes_decrypt(&ctx, t->ctext, out, AES_BLOCK_LEN); aes_finish(&ctx); - return (t_compare_mem(t->ptext, out, AES_BLOCK_LEN)); + ret = t_compare_sz(AES_BLOCK_LEN, len) & + t_compare_mem(t->ptext, out, AES_BLOCK_LEN); + return (ret); } diff --git a/t/t_rc4.c b/t/t_rc4.c index 1b9ffda..d6788a4 100644 --- a/t/t_rc4.c +++ b/t/t_rc4.c @@ -1975,7 +1975,7 @@ t_rc4(char **desc CRYB_UNUSED, void *arg) rc4_init(&ctx, CIPHER_MODE_ENCRYPT, t->key, t->keylen); for (i = offset = 0; i < 18; ++i) { do { - rc4_update(&ctx, t_zero, 16, out); + rc4_encrypt(&ctx, t_zero, out, 16); offset += 16; } while (offset <= t->out[i].offset); ret &= t_compare_mem(t->out[i].bytes, out, 16);