Commit 22d838ba authored by Davide Galassi's avatar Davide Galassi

Merge branch 'feature/cfb_block_mode_of_operation' into 'master'

Feature CFB block mode of operation

Closes #4

See merge request !8
parents 8dfca2a7 101752bd
Pipeline #45868963 passed with stages
in 1 minute and 14 seconds
......@@ -21,6 +21,12 @@ Given a version number MAJOR.MINOR.PATCH
- MINOR incremented for new functionalities
- PATCH incremented for bug fixes
[0.0.8] - Unreleased
--------------------
- CFB block cipher mode of operation
[0.0.7] - 2018-12-26
--------------------
......@@ -69,8 +75,6 @@ Given a version number MAJOR.MINOR.PATCH
[0.0.2] - 2014-11-22
--------------------
### Added
- LRC
- 8-bit trivial checksum
- CRC16-IBM
......@@ -80,8 +84,6 @@ Given a version number MAJOR.MINOR.PATCH
[0.0.1] - 2014-05-10
--------------------
### Added
- AES block cipher
- DES block cipher
- CBC block cipher mode of operation
......@@ -92,4 +94,3 @@ Given a version number MAJOR.MINOR.PATCH
- CMAC message authentication code
- Base64 encoder/decoder
- CRC16-CCITT
[![Build Status](https://travis-ci.com/crylib/cry.svg?branch=master)](https://travis-ci.com/crylib/cry)
[![Coverage Status](https://coveralls.io/repos/github/crylib/cry/badge.svg?branch=master)](https://coveralls.io/github/crylib/cry?branch=master)
CRY
===
CRY is a small, comprehensive and portable cryptographic library prividing
a good collection of ciphers, hash functions, chaining modes, pseudo-random
number generators and checksums.
a good collection of ciphers, hash functions, pseudo-random number generators
and multi-precision integers algorithms.
Multiple precision integers
......@@ -26,15 +27,20 @@ Symmetric ciphers
### Block ciphers
- AES
- AES (Rijndael)
- DES and Triple DES
### Block cipher mode of operation
### Block ciphers mode of operation
- ECB (electronic codebook)
- CBC (cipher block chaining)
- CFB (cipher feedback)
- CTR (counter)
- GCM (Galois counter mode)
### Stream ciphers
- ECB
- CBC
- GCM
- CTR
- Trivium
Public key algorithms
......@@ -60,16 +66,16 @@ Elliptic Curve
--------------
- Basic arithmetic (add,dbl,mul)
- Load of NIST-P256 EC parameters
- NIST-P256 EC parameters
Pseudo random numbers generators
--------------------------------
- OS agnostic CSPRNG with AES-CTR
- Weak portable PRNG
- AES-CTR CSPRNG
- Posix CSPRNG (using '/dev/urandom')
- Windows CSPRNG (using 'CryptGenRandom')
- Weak portable PRNG
Message authentication code
---------------------------
......@@ -81,7 +87,7 @@ Message authentication code
Hash
----
### Cryptographic hash
### Secure hash
- MD5
- SHA-256
......@@ -95,7 +101,7 @@ Hash
### Checksums
- LRC
- 8-bit trivial checksum
- Trivial checksum
Classical ciphers
......@@ -111,4 +117,4 @@ Utilities
---------
- Base64 encoder/decoder
- Memxor
/**
* @file cfb.h
*
* @brief CFB block cipher mode of operation.
*
* The Cipher Feedback (CFB) mode, a close relative of CBC, makes a block
* cipher into a self-synchronizing stream cipher. Operation is very
* similar; in particular, CFB decryption is almost identical to CBC
* encryption performed in reverse.
*/
#ifndef CRY_CFB_H_
#define CRY_CFB_H_
#include <cry/ciph.h>
/** Block size. */
#define CRY_CFB_BLOCK_MAX 16
/**
* CFB context.
*/
struct cry_cfb_ctx {
/** Cipher context. */
void *ciph_ctx;
/** Cipher interface. */
const struct cry_ciph_itf *ciph_itf;
/** Initialization vector length */
unsigned int vlen;
/** Initialization vector data. */
unsigned char v[CRY_CFB_BLOCK_MAX];
};
typedef struct cry_cfb_ctx cry_cfb_ctx;
#ifdef __cplusplus
extern "C"{
#endif
/**
* Context initialization.
*
* @param ctx CFB context.
* @param ciph_ctx Cipher context.
* @param ciph_itf Cipher interface.
*/
void cry_cfb_init(struct cry_cfb_ctx *ctx, void *ciph_ctx,
const struct cry_ciph_itf *ciph_itf);
/**
* Set the cipher key in the cipher context.
*
* @param ctx CFB context.
* @param key Cipher key.
* @param size Size of cipher key.
*/
void cry_cfb_key_set(struct cry_cfb_ctx *ctx, const unsigned char *key,
unsigned int size);
/**
* Set the initialization vector in the CFB context.
*
* @param ctx CFB context.
* @param iv Initialization vector.
* @param size Size of initialization vector (<= CRY_CFB_BLOCK_SIZE).
*/
void cry_cfb_iv_set(struct cry_cfb_ctx *ctx, const unsigned char *iv,
unsigned int size);
/**
* Encrypt/Decrypt function.
*
* @param ctx CFB context.
* @param dst Destination pointer.
* @param src Source pointer.
* @param size Size of source/destination.
*/
void cry_cfb_crypt(struct cry_cfb_ctx *ctx, unsigned char *dst,
const unsigned char *src, unsigned int size);
/**
* Encryption function.
*
* @param ctx CFB context.
* @param dst Destination pointer (ciphertext).
* @param src Source pointer (cleartext).
* @param size Size of cleartext.
*/
#define cry_cfb_encrypt cry_cfb_crypt
/**
* Decryption function.
*
* @param ctx CFB context.
* @param dst Destination pointer (cleartext).
* @param src Source pointer (ciphertext).
* @param size Size of ciphertext.
*/
#define cry_cfb_decrypt cry_cfb_crypt
/**
* Encryption function.
*
* @param ctx CFB context.
* @param dst Destination pointer (ciphertext).
* @param src Source pointer (cleartext).
* @param size Size of source/destination.
*/
void cry_cfb8_encrypt(struct cry_cfb_ctx *ctx, unsigned char *dst,
const unsigned char *src, unsigned int size);
/**
* Decryption function.
*
* @param ctx CFB context.
* @param dst Destination pointer (cleartext).
* @param src Source pointer (ciphertext).
* @param size Size of ciphertext.
*/
void cry_cfb8_decrypt(struct cry_cfb_ctx *ctx, unsigned char *dst,
const unsigned char *src, unsigned int size);
#ifdef __cplusplus
}
#endif
#endif /* CRY_CFB_H_ */
......@@ -11,7 +11,7 @@
* To decrypt the message each ciphertext block of n octets is instead left
* multiplied by the inverse matrix A^-1.
*
* Given the cleartext x=<x1,...,xn> and the ciphertext y=<x1...yn>
* Given the cleartext x=<x1,...,xn> and the ciphertext y=<x1...yn>
* Encryption function: E(x) = A * x = y
* Encryption function: D(y) = A^-1 * y = x
*
......
......@@ -53,4 +53,3 @@ int cry_affine_init(struct cry_affine_ctx *ctx, const unsigned char *keya,
}
return res;
}
#include <cry/cfb.h>
#include "memxor.h"
#include "misc.h"
#include <string.h>
void cry_cfb_init(struct cry_cfb_ctx *ctx, void *ciph_ctx,
const struct cry_ciph_itf *ciph_itf)
{
memset(ctx->v, 0, sizeof(ctx->v));
ctx->ciph_ctx = ciph_ctx;
ctx->ciph_itf = ciph_itf;
}
void cry_cfb_key_set(struct cry_cfb_ctx *ctx, const unsigned char *key,
unsigned int size)
{
void *ciph = ctx->ciph_ctx;
cry_ciph_key_set_f key_set = ctx->ciph_itf->key_set;
key_set(ciph, key, size);
}
void cry_cfb_iv_set(struct cry_cfb_ctx *ctx, const unsigned char *iv,
unsigned int size)
{
ctx->vlen = CRY_MIN(CRY_CFB_BLOCK_MAX, size);
memcpy(ctx->v, iv, ctx->vlen);
memset(ctx->v + ctx->vlen, 0, CRY_CFB_BLOCK_MAX - ctx->vlen);
}
void cry_cfb_crypt(struct cry_cfb_ctx *ctx, unsigned char *dst,
const unsigned char *src, unsigned int len)
{
void *ciph = ctx->ciph_ctx;
cry_ciph_encrypt_f encrypt = ctx->ciph_itf->encrypt;
size_t n;
for (n = len; n >= ctx->vlen; n -= ctx->vlen) {
encrypt(ciph, ctx->v, ctx->v, ctx->vlen);
cry_memxor2(dst, src, ctx->v, ctx->vlen);
memcpy(ctx->v, dst, ctx->vlen);
src += ctx->vlen;
dst += ctx->vlen;
}
if (n != 0) {
encrypt(ciph, ctx->v, ctx->v, ctx->vlen);
cry_memxor2(dst, src, ctx->v, n);
memcpy(ctx->v, dst, ctx->vlen);
}
}
void cry_cfb8_encrypt(struct cry_cfb_ctx *ctx, unsigned char *dst,
const unsigned char *src, unsigned int len)
{
void *ciph = ctx->ciph_ctx;
cry_ciph_encrypt_f encrypt = ctx->ciph_itf->encrypt;
size_t pos;
unsigned char buf[CRY_CFB_BLOCK_MAX * 2];
memcpy(buf, ctx->v, ctx->vlen);
pos = 0;
while (len != 0) {
if (pos == ctx->vlen) {
memcpy(buf, buf + ctx->vlen, ctx->vlen);
pos = 0;
}
encrypt(ciph, ctx->v, buf + pos, ctx->vlen);
buf[pos + ctx->vlen] = *(dst++) = *(src++) ^ ctx->v[0];
len--;
pos++;
}
memcpy(ctx->v, buf + pos, ctx->vlen);
}
void cry_cfb8_decrypt(struct cry_cfb_ctx *ctx, unsigned char *dst,
const unsigned char *src, unsigned int len)
{
void *ciph = ctx->ciph_ctx;
cry_ciph_encrypt_f encrypt = ctx->ciph_itf->encrypt;
size_t i = 0;
unsigned char buf[CRY_CFB_BLOCK_MAX * 2];
unsigned char obuf[CRY_CFB_BLOCK_MAX * 2];
memcpy(buf, ctx->v, ctx->vlen);
memcpy(buf + ctx->vlen, src, len < ctx->vlen ? len : ctx->vlen);
while (len != 0) {
for (i = 0; i < len && i < ctx->vlen; i++)
encrypt(ciph, obuf + i, buf + i, ctx->vlen);
cry_memxor2(dst, src, obuf, i);
len -= i;
src += i;
dst += i;
memcpy(buf, buf + ctx->vlen, ctx->vlen);
memcpy(buf + ctx->vlen, src, len < ctx->vlen ? len : ctx->vlen);
}
memcpy(ctx->v, buf + i, ctx->vlen);
}
......@@ -77,7 +77,7 @@ static const unsigned char p_tab[] = {
/* S-Box table.
* In textbooks, the presented S-Box table is usually constructed by
* interpreting the six bits input as
* interpreting the six bits input as
* [ R1 | C3 | C2 | C1 | C0 | R0 ]
* Thus, for example, the output for the bit string 101100 is found
* in row 2 and column 6.
......
......@@ -6,6 +6,7 @@ objects-y := \
des.o \
cbc.o \
ctr.o \
cfb.o \
gcm.o \
rsa.o \
trivium.o \
......
......@@ -154,7 +154,7 @@ static void operate(cry_trivium_ctx *ctx, unsigned char *dst,
UPDATE();
ROTATE();
for ( ; i < size; i++, z >>= 8)
dst[i] = src[i] ^ (uint8_t)(z);
dst[i] = src[i] ^ (uint8_t)(z);
}
STORE(ctx->s);
......
This diff is collapsed.
......@@ -2,6 +2,7 @@
#include <cry/aes.h>
#include <cry/cbc.h>
#include <cry/ctr.h>
#include <cry/cfb.h>
#include <cry/gcm.h>
......@@ -90,7 +91,7 @@ static void aes_cbc_encrypt(int argc, char *argv[])
cry_cbc_init(&ctx, &aes_ctx, &aes_itf);
cry_cbc_key_set(&ctx, par.key, par.keylen);
cry_cbc_iv_set(&ctx, par.iv, 16);
cry_cbc_iv_set(&ctx, par.iv, par.ivlen);
cry_cbc_encrypt(&ctx, dst, par.src, par.srclen);
ASSERT_EQ_BUF(dst, par.dst, par.srclen);
......@@ -108,7 +109,7 @@ static void aes_cbc_decrypt(int argc, char *argv[])
cry_cbc_init(&ctx, &aes_ctx, &aes_itf);
cry_cbc_key_set(&ctx, par.key, par.keylen);
cry_cbc_iv_set(&ctx, par.iv, 16);
cry_cbc_iv_set(&ctx, par.iv, par.ivlen);
cry_cbc_decrypt(&ctx, dst, par.src, par.srclen);
ASSERT_EQ_BUF(dst, par.dst, par.srclen);
......@@ -126,7 +127,7 @@ static void aes_ctr_encrypt(int argc, char *argv[])
cry_ctr_init(&ctx, &aes_ctx, &aes_itf);
cry_ctr_key_set(&ctx, par.key, par.keylen);
cry_ctr_iv_set(&ctx, par.iv, 16);
cry_ctr_iv_set(&ctx, par.iv, par.ivlen);
cry_ctr_encrypt(&ctx, dst, par.src, par.srclen);
ASSERT_EQ_BUF(dst, par.dst, par.srclen);
......@@ -144,12 +145,54 @@ static void aes_ctr_decrypt(int argc, char *argv[])
cry_ctr_init(&ctx, &aes_ctx, &aes_itf);
cry_ctr_key_set(&ctx, par.key, par.keylen);
cry_ctr_iv_set(&ctx, par.iv, 16);
cry_ctr_iv_set(&ctx, par.iv, par.ivlen);
cry_ctr_decrypt(&ctx, dst, par.src, par.srclen);
ASSERT_EQ_BUF(dst, par.dst, par.srclen);
}
static void aes_cfb_encrypt(int argc, char *argv[], int do8)
{
cry_cfb_ctx ctx;
cry_aes_ctx aes_ctx;
struct aes_param par;
unsigned char dst[32];
ASSERT(argc == 4);
param_init(&par, argc, argv);
cry_cfb_init(&ctx, &aes_ctx, &aes_itf);
cry_cfb_key_set(&ctx, par.key, par.keylen);
cry_cfb_iv_set(&ctx, par.iv, par.ivlen);
if (do8 == 0)
cry_cfb_encrypt(&ctx, dst, par.src, par.srclen);
else
cry_cfb8_encrypt(&ctx, dst, par.src, par.srclen);
ASSERT_EQ_BUF(dst, par.dst, par.srclen);
}
static void aes_cfb_decrypt(int argc, char *argv[], int do8)
{
cry_cfb_ctx ctx;
cry_aes_ctx aes_ctx;
struct aes_param par;
unsigned char dst[32];
ASSERT(argc == 4);
param_init(&par, argc, argv);
cry_cfb_init(&ctx, &aes_ctx, &aes_itf);
cry_cfb_key_set(&ctx, par.key, par.keylen);
cry_cfb_iv_set(&ctx, par.iv, par.ivlen);
if (do8 == 0)
cry_cfb_decrypt(&ctx, dst, par.src, par.srclen);
else
cry_cfb8_decrypt(&ctx, dst, par.src, par.srclen);
ASSERT_EQ_BUF(dst, par.dst, par.srclen);
}
static void aes_gcm_encrypt(int argc, char *argv[])
{
cry_gcm_ctx ctx;
......@@ -163,7 +206,7 @@ static void aes_gcm_encrypt(int argc, char *argv[])
cry_gcm_init(&ctx, &aes_ctx, &aes_itf);
cry_gcm_key_set(&ctx, par.key, par.keylen);
cry_gcm_iv_set(&ctx, par.iv, 16);
cry_gcm_iv_set(&ctx, par.iv, par.ivlen);
cry_gcm_update(&ctx, par.aad, par.aadlen);
cry_gcm_encrypt(&ctx, dst, par.src, par.srclen);
cry_gcm_digest(&ctx, mac, par.maclen);
......@@ -185,7 +228,7 @@ static void aes_gcm_decrypt(int argc, char *argv[])
cry_gcm_init(&ctx, &aes_ctx, &aes_itf);
cry_gcm_key_set(&ctx, par.key, par.keylen);
cry_gcm_iv_set(&ctx, par.iv, 16);
cry_gcm_iv_set(&ctx, par.iv, par.ivlen);
cry_gcm_update(&ctx, par.aad, par.aadlen);
cry_gcm_decrypt(&ctx, dst, par.src, par.srclen);
cry_gcm_digest(&ctx, mac, par.maclen);
......@@ -218,6 +261,14 @@ static void dispatch(int argc, char *argv[])
aes_ctr_encrypt(argc, argv);
else if (strcmp(test, "aes_ctr_decrypt") == 0)
aes_ctr_decrypt(argc, argv);
else if (strcmp(test, "aes_cfb_encrypt") == 0)
aes_cfb_encrypt(argc, argv, 0);
else if (strcmp(test, "aes_cfb_decrypt") == 0)
aes_cfb_decrypt(argc, argv, 0);
else if (strcmp(test, "aes_cfb8_encrypt") == 0)
aes_cfb_encrypt(argc, argv, 1);
else if (strcmp(test, "aes_cfb8_decrypt") == 0)
aes_cfb_decrypt(argc, argv, 1);
else if (strcmp(test, "aes_gcm_encrypt") == 0)
aes_gcm_encrypt(argc, argv);
else if (strcmp(test, "aes_gcm_decrypt") == 0)
......@@ -230,7 +281,7 @@ void aes_test(void)
{
printf("* AES NIST AESAVS KAT\n");
func_test("aes_kat_test.data", dispatch);
printf("* AES NIST GCM Validation\n");
printf("* AES GCM NIST Validation\n");
func_test("aes_gcm_test.data", dispatch);
printf("\n");
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment