aboutsummaryrefslogtreecommitdiff
path: root/gost_grasshopper_cipher.c
diff options
context:
space:
mode:
authorVitaly Chikunov <vt@altlinux.org>2018-07-28 10:36:29 +0300
committerVitaly Chikunov <vt@altlinux.org>2018-07-31 11:45:48 +0300
commitae390d45207aadb69eb96d8c11c1ee888f70815f (patch)
tree39dff94b25ee0f787058b233e9ef3ff2f9f4e323 /gost_grasshopper_cipher.c
parent2be13cb5c7e96d6bdead59b37717c2f49a581e9e (diff)
downloadgost-engine-ae390d45207aadb69eb96d8c11c1ee888f70815f.zip
gost-engine-ae390d45207aadb69eb96d8c11c1ee888f70815f.tar.gz
gost-engine-ae390d45207aadb69eb96d8c11c1ee888f70815f.tar.bz2
Optimize out skip_sections and add tests for ACPKM-Master
ACPKM-Master is from R 23565.1.017-2018, it will be required for ACPKM-OMAC for TLS 1.2.
Diffstat (limited to 'gost_grasshopper_cipher.c')
-rw-r--r--gost_grasshopper_cipher.c26
1 files changed, 9 insertions, 17 deletions
diff --git a/gost_grasshopper_cipher.c b/gost_grasshopper_cipher.c
index 528a7ee..e78fae7 100644
--- a/gost_grasshopper_cipher.c
+++ b/gost_grasshopper_cipher.c
@@ -126,9 +126,8 @@ static const unsigned char ACPKM_D_2018[] = {
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 256 bit */
};
-static void acpkm_grasshopper(gost_grasshopper_cipher_ctx_ctr *ctx)
+static void acpkm_next(gost_grasshopper_cipher_ctx *c)
{
- gost_grasshopper_cipher_ctx *c = &ctx->c;
unsigned char newkey[GRASSHOPPER_KEY_SIZE];
const int J = GRASSHOPPER_KEY_SIZE / GRASSHOPPER_BLOCK_SIZE;
int n;
@@ -265,7 +264,6 @@ GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_ctracpkm(EVP_CIPHER_CTX *ctx
c->c.type = GRASSHOPPER_CIPHER_CTRACPKM;
EVP_CIPHER_CTX_set_num(ctx, 0);
c->section_size = 4096;
- c->skip_sections = 1;
return gost_grasshopper_cipher_init(ctx, key, iv, enc);
}
@@ -403,20 +401,16 @@ int gost_grasshopper_cipher_do_ctr(EVP_CIPHER_CTX* ctx, unsigned char* out,
return 1;
}
-static inline void apply_acpkm_grasshopper(gost_grasshopper_cipher_ctx_ctr *ctx, unsigned int num)
+#define GRASSHOPPER_BLOCK_MASK (GRASSHOPPER_BLOCK_SIZE - 1)
+static inline void apply_acpkm_grasshopper(gost_grasshopper_cipher_ctx_ctr *ctx, unsigned int *num)
{
if (!ctx->section_size ||
- (num & (ctx->section_size - 1)))
- return;
- if (ctx->skip_sections) {
- /* In no master key mode first section is using original key */
- --ctx->skip_sections;
+ (*num < ctx->section_size))
return;
- }
- acpkm_grasshopper(ctx);
+ acpkm_next(&ctx->c);
+ *num &= GRASSHOPPER_BLOCK_MASK;
}
-#define GRASSHOPPER_BLOCK_MASK (GRASSHOPPER_BLOCK_SIZE - 1)
/* If meshing is not configured via ctrl (setting section_size)
* this function works exactly like plain ctr */
int gost_grasshopper_cipher_do_ctracpkm(EVP_CIPHER_CTX *ctx, unsigned char *out,
@@ -435,7 +429,7 @@ int gost_grasshopper_cipher_do_ctracpkm(EVP_CIPHER_CTX *ctx, unsigned char *out,
// full parts
for (i = 0; i < blocks; i++) {
- apply_acpkm_grasshopper(c, num);
+ apply_acpkm_grasshopper(c, &num);
grasshopper_encrypt_block(&c->c.encrypt_round_keys,
(grasshopper_w128_t *)iv, (grasshopper_w128_t *)out, &c->c.buffer);
grasshopper_append128((grasshopper_w128_t *)out, (grasshopper_w128_t *)in);
@@ -448,7 +442,7 @@ int gost_grasshopper_cipher_do_ctracpkm(EVP_CIPHER_CTX *ctx, unsigned char *out,
// last part
size_t lasted = inl - blocks * GRASSHOPPER_BLOCK_SIZE;
if (lasted > 0) {
- apply_acpkm_grasshopper(c, num);
+ apply_acpkm_grasshopper(c, &num);
grasshopper_encrypt_block(&c->c.encrypt_round_keys,
(grasshopper_w128_t *)iv, &c->partial_buffer, &c->c.buffer);
for (i = 0; i < lasted; i++)
@@ -662,11 +656,9 @@ int gost_grasshopper_cipher_ctl(EVP_CIPHER_CTX* ctx, int type, int arg, void* pt
case EVP_CTRL_KEY_MESH: {
gost_grasshopper_cipher_ctx_ctr *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
if (c->c.type != GRASSHOPPER_CIPHER_CTRACPKM ||
- arg <= 1 ||
- ((arg - 1) & arg))
+ !arg || (arg % GRASSHOPPER_BLOCK_SIZE))
return -1;
c->section_size = arg;
- c->skip_sections = 1;
break;
}
default: