Add OFB mode.
Change-Id: I267cf7897b5a9f73f8de729971cb9e92937011dd
diff --git a/crypto/cipher/cipher.c b/crypto/cipher/cipher.c
index 4dccd97..695b7f3 100644
--- a/crypto/cipher/cipher.c
+++ b/crypto/cipher/cipher.c
@@ -197,7 +197,6 @@
break;
case EVP_CIPH_CFB_MODE:
- case EVP_CIPH_OFB_MODE:
ctx->num = 0;
/* fall-through */
@@ -210,6 +209,7 @@
break;
case EVP_CIPH_CTR_MODE:
+ case EVP_CIPH_OFB_MODE:
ctx->num = 0;
/* Don't reuse IV for CTR mode */
if (iv) {
diff --git a/crypto/cipher/cipher_test.c b/crypto/cipher/cipher_test.c
index 55db93e..607111f 100644
--- a/crypto/cipher/cipher_test.c
+++ b/crypto/cipher/cipher_test.c
@@ -311,6 +311,8 @@
c = EVP_aes_128_cbc();
} else if (strcmp(cipher, "AES-128-GCM") == 0) {
c = EVP_aes_128_gcm();
+ } else if (strcmp(cipher, "AES-128-OFB") == 0) {
+ c = EVP_aes_128_ofb();
} else if (strcmp(cipher, "AES-256-CBC") == 0) {
c = EVP_aes_256_cbc();
} else if (strcmp(cipher, "AES-128-CTR") == 0) {
@@ -319,6 +321,8 @@
c = EVP_aes_256_ctr();
} else if (strcmp(cipher, "AES-256-GCM") == 0) {
c = EVP_aes_256_gcm();
+ } else if (strcmp(cipher, "AES-256-OFB") == 0) {
+ c = EVP_aes_256_ofb();
} else {
fprintf(stderr, "Unknown cipher type %s\n", cipher);
return 0;
diff --git a/crypto/cipher/e_aes.c b/crypto/cipher/e_aes.c
index f463176..8b967dd 100644
--- a/crypto/cipher/e_aes.c
+++ b/crypto/cipher/e_aes.c
@@ -344,8 +344,8 @@
return 1;
}
-static int aes_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
- const unsigned char *in, size_t len) {
+static int aes_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
+ size_t len) {
EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
if (dat->stream.cbc) {
@@ -359,8 +359,8 @@
return 1;
}
-static int aes_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
- const unsigned char *in, size_t len) {
+static int aes_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
+ size_t len) {
size_t bl = ctx->cipher->block_size;
size_t i;
EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
@@ -376,8 +376,8 @@
return 1;
}
-static int aes_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
- const unsigned char *in, size_t len) {
+static int aes_ctr_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
+ size_t len) {
unsigned int num = ctx->num;
EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
@@ -392,6 +392,14 @@
return 1;
}
+static int aes_ofb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
+ size_t len) {
+ EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
+
+ CRYPTO_ofb128_encrypt(in, out, len, &dat->ks, ctx->iv, &ctx->num, dat->block);
+ return 1;
+}
+
static char aesni_capable(void);
static ctr128_f aes_ctr_set_key(AES_KEY *aes_key, GCM128_CONTEXT *gcm_ctx,
@@ -733,6 +741,12 @@
NULL /* app_data */, aes_init_key, aes_ecb_cipher,
NULL /* cleanup */, NULL /* ctrl */};
+static const EVP_CIPHER aes_128_ofb = {
+ NID_aes_128_ofb128, 1 /* block_size */, 16 /* key_size */,
+ 16 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_OFB_MODE,
+ NULL /* app_data */, aes_init_key, aes_ofb_cipher,
+ NULL /* cleanup */, NULL /* ctrl */};
+
static const EVP_CIPHER aes_128_gcm = {
NID_aes_128_gcm, 1 /* block_size */, 16 /* key_size */, 12 /* iv_len */,
sizeof(EVP_AES_GCM_CTX),
@@ -761,6 +775,12 @@
NULL /* app_data */, aes_init_key, aes_ecb_cipher,
NULL /* cleanup */, NULL /* ctrl */};
+static const EVP_CIPHER aes_256_ofb = {
+ NID_aes_256_ofb128, 1 /* block_size */, 32 /* key_size */,
+ 16 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_OFB_MODE,
+ NULL /* app_data */, aes_init_key, aes_ofb_cipher,
+ NULL /* cleanup */, NULL /* ctrl */};
+
static const EVP_CIPHER aes_256_gcm = {
NID_aes_256_gcm, 1 /* block_size */, 32 /* key_size */, 12 /* iv_len */,
sizeof(EVP_AES_GCM_CTX),
@@ -881,6 +901,12 @@
NULL /* app_data */, aesni_init_key, aesni_ecb_cipher,
NULL /* cleanup */, NULL /* ctrl */};
+static const EVP_CIPHER aesni_128_ofb = {
+ NID_aes_128_ofb128, 1 /* block_size */, 16 /* key_size */,
+ 16 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_OFB_MODE,
+ NULL /* app_data */, aesni_init_key, aes_ofb_cipher,
+ NULL /* cleanup */, NULL /* ctrl */};
+
static const EVP_CIPHER aesni_128_gcm = {
NID_aes_128_gcm, 1 /* block_size */, 16 /* key_size */, 12 /* iv_len */,
sizeof(EVP_AES_GCM_CTX),
@@ -909,6 +935,12 @@
NULL /* app_data */, aesni_init_key, aesni_ecb_cipher,
NULL /* cleanup */, NULL /* ctrl */};
+static const EVP_CIPHER aesni_256_ofb = {
+ NID_aes_256_ofb128, 1 /* block_size */, 32 /* key_size */,
+ 16 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_OFB_MODE,
+ NULL /* app_data */, aesni_init_key, aes_ofb_cipher,
+ NULL /* cleanup */, NULL /* ctrl */};
+
static const EVP_CIPHER aesni_256_gcm = {
NID_aes_256_gcm, 1 /* block_size */, 32 /* key_size */, 12 /* iv_len */,
sizeof(EVP_AES_GCM_CTX),
@@ -943,11 +975,13 @@
EVP_CIPHER_FUNCTION(128, cbc)
EVP_CIPHER_FUNCTION(128, ctr)
EVP_CIPHER_FUNCTION(128, ecb)
+EVP_CIPHER_FUNCTION(128, ofb)
EVP_CIPHER_FUNCTION(128, gcm)
EVP_CIPHER_FUNCTION(256, cbc)
EVP_CIPHER_FUNCTION(256, ctr)
EVP_CIPHER_FUNCTION(256, ecb)
+EVP_CIPHER_FUNCTION(256, ofb)
EVP_CIPHER_FUNCTION(256, gcm)
diff --git a/crypto/cipher/test/cipher_test.txt b/crypto/cipher/test/cipher_test.txt
index a4b168b..17914e5 100644
--- a/crypto/cipher/test/cipher_test.txt
+++ b/crypto/cipher/test/cipher_test.txt
@@ -81,3 +81,23 @@
# 80 bytes plaintext, submitted by Intel
AES-128-GCM:843ffcf5d2b72694d19ed01d01249412:dbcca32ebf9b804617c3aa9e:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f:6268c6fa2a80b2d137467f092f657ac04d89be2beaa623d61b5a868c8f03ff95d3dcee23ad2f1ab3a6c80eaf4b140eb05de3457f0fbc111a6b43d0763aa422a3013cf1dc37fe417d1fbfc449b75d4cc5:00000000000000000000000000000000101112131415161718191a1b1c1d1e1f:3b629ccfbc1119b7319e1dce2cd6fd6d
+# OFB tests from OpenSSL upstream.
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:1
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:7789508D16918F03F53C52DAC54ED825:1
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:9740051E9C5FECF64344F7A82260EDCC:1
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:304C6528F659C77866A510D9C1D6AE5E:1
+# OFB-AES128.Decrypt
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:0
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:7789508D16918F03F53C52DAC54ED825:0
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:9740051E9C5FECF64344F7A82260EDCC:0
+AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:304C6528F659C77866A510D9C1D6AE5E:0
+# OFB-AES256.Encrypt
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:1
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:4FEBDC6740D20B3AC88F6AD82A4FB08D:1
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:71AB47A086E86EEDF39D1C5BBA97C408:1
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0126141D67F37BE8538F5A8BE740E484:1
+# OFB-AES256.Decrypt
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:0
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:4FEBDC6740D20B3AC88F6AD82A4FB08D:0
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:71AB47A086E86EEDF39D1C5BBA97C408:0
+AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0126141D67F37BE8538F5A8BE740E484:0
diff --git a/include/openssl/cipher.h b/include/openssl/cipher.h
index 1df4699..bc69378 100644
--- a/include/openssl/cipher.h
+++ b/include/openssl/cipher.h
@@ -80,10 +80,12 @@
OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_ecb(void);
OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_cbc(void);
OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_ctr(void);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_ofb(void);
OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_ecb(void);
OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_cbc(void);
OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_ctr(void);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_ofb(void);
/* Deprecated AES-GCM implementations that set |EVP_CIPH_FLAG_CUSTOM_CIPHER|.
* Use |EVP_aead_aes_128_gcm| and |EVP_aead_aes_256_gcm| instead. */