mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
g10/armor: use libgcrypt's CRC24 implementation
* g10/armor.c (CRCINIT, CRCPOLY, CRCUPDATE, crc_table): Remove. (new_armor_context): Open libgcrypt CRC24 context. (release_armor_context): Close CRC24 context. (initialize): Remove CRC table generation. (get_afx_crc): New. (check_input, fake_packet, radix64_read, armor_filter): Update to use CRC24 context. * g10/filter.h (armor_filter_context_t): Replace crc intermediate value with libgcrypt md context pointer. -- This patch changes armor filter to use optimized CRC24 implementation from libgcrypt to speed up encryption and decryption. Benchmark results below, tested on Intel Core i7-4790K (turbo off). Encrypted 2 GiB through pipe to ramfs file using AES128. Decrypt ramfs file out through pipe to /dev/null. before patch-set ---------------- gpg process armor: user time pipe transfer rate encrypt-aead: 13.8 140 MB/s decrypt-aead: 30.6 68 MB/s encrypt-cfb: 17.4 114 MB/s decrypt-cfb: 32.6 64 MB/s after (decrypt+iobuf+crc opt) ----------------------------- gpg process armor: user time pipe transfer rate encrypt-aead: 8.7 211 MB/s decrypt-aead: 17.6 116 MB/s encrypt-cfb: 12.6 153 MB/s decrypt-cfb: 19.6 105 MB/s Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
This commit is contained in:
parent
2b5718c1f7
commit
e486d4f025
97
g10/armor.c
97
g10/armor.c
@ -37,13 +37,6 @@
|
|||||||
|
|
||||||
#define MAX_LINELEN 20000
|
#define MAX_LINELEN 20000
|
||||||
|
|
||||||
#define CRCINIT 0xB704CE
|
|
||||||
#define CRCPOLY 0X864CFB
|
|
||||||
#define CRCUPDATE(a,c) do { \
|
|
||||||
a = ((a) << 8) ^ crc_table[((a)&0xff >> 16) ^ (c)]; \
|
|
||||||
a &= 0x00ffffff; \
|
|
||||||
} while(0)
|
|
||||||
static u32 crc_table[256];
|
|
||||||
static byte bintoasc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
static byte bintoasc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
"abcdefghijklmnopqrstuvwxyz"
|
"abcdefghijklmnopqrstuvwxyz"
|
||||||
"0123456789+/";
|
"0123456789+/";
|
||||||
@ -121,9 +114,22 @@ armor_filter_context_t *
|
|||||||
new_armor_context (void)
|
new_armor_context (void)
|
||||||
{
|
{
|
||||||
armor_filter_context_t *afx;
|
armor_filter_context_t *afx;
|
||||||
|
gpg_error_t err;
|
||||||
|
|
||||||
afx = xcalloc (1, sizeof *afx);
|
afx = xcalloc (1, sizeof *afx);
|
||||||
afx->refcount = 1;
|
if (afx)
|
||||||
|
{
|
||||||
|
err = gcry_md_open (&afx->crc_md, GCRY_MD_CRC24_RFC2440, 0);
|
||||||
|
if (err != 0)
|
||||||
|
{
|
||||||
|
log_error ("gcry_md_open failed for GCRY_MD_CRC24_RFC2440: %s",
|
||||||
|
gpg_strerror (err));
|
||||||
|
xfree (afx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
afx->refcount = 1;
|
||||||
|
}
|
||||||
|
|
||||||
return afx;
|
return afx;
|
||||||
}
|
}
|
||||||
@ -138,6 +144,7 @@ release_armor_context (armor_filter_context_t *afx)
|
|||||||
log_assert (afx->refcount);
|
log_assert (afx->refcount);
|
||||||
if ( --afx->refcount )
|
if ( --afx->refcount )
|
||||||
return;
|
return;
|
||||||
|
gcry_md_close (afx->crc_md);
|
||||||
xfree (afx);
|
xfree (afx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,25 +168,8 @@ push_armor_filter (armor_filter_context_t *afx, iobuf_t iobuf)
|
|||||||
static void
|
static void
|
||||||
initialize(void)
|
initialize(void)
|
||||||
{
|
{
|
||||||
int i, j;
|
u32 i;
|
||||||
u32 t;
|
|
||||||
byte *s;
|
byte *s;
|
||||||
|
|
||||||
/* init the crc lookup table */
|
|
||||||
crc_table[0] = 0;
|
|
||||||
for(i=j=0; j < 128; j++ ) {
|
|
||||||
t = crc_table[j];
|
|
||||||
if( t & 0x00800000 ) {
|
|
||||||
t <<= 1;
|
|
||||||
crc_table[i++] = t ^ CRCPOLY;
|
|
||||||
crc_table[i++] = t;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
t <<= 1;
|
|
||||||
crc_table[i++] = t;
|
|
||||||
crc_table[i++] = t ^ CRCPOLY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* build the helptable for radix64 to bin conversion */
|
/* build the helptable for radix64 to bin conversion */
|
||||||
for(i=0; i < 256; i++ )
|
for(i=0; i < 256; i++ )
|
||||||
asctobin[i] = 255; /* used to detect invalid characters */
|
asctobin[i] = 255; /* used to detect invalid characters */
|
||||||
@ -190,6 +180,24 @@ initialize(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline u32
|
||||||
|
get_afx_crc (armor_filter_context_t *afx)
|
||||||
|
{
|
||||||
|
const byte *crc_buf;
|
||||||
|
u32 crc;
|
||||||
|
|
||||||
|
crc_buf = gcry_md_read (afx->crc_md, GCRY_MD_CRC24_RFC2440);
|
||||||
|
|
||||||
|
crc = crc_buf[0];
|
||||||
|
crc <<= 8;
|
||||||
|
crc |= crc_buf[1];
|
||||||
|
crc <<= 8;
|
||||||
|
crc |= crc_buf[2];
|
||||||
|
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check whether this is an armored file. See also
|
* Check whether this is an armored file. See also
|
||||||
* parse-packet.c for details on this code.
|
* parse-packet.c for details on this code.
|
||||||
@ -592,7 +600,7 @@ check_input( armor_filter_context_t *afx, IOBUF a )
|
|||||||
afx->faked = 1;
|
afx->faked = 1;
|
||||||
else {
|
else {
|
||||||
afx->inp_checked = 1;
|
afx->inp_checked = 1;
|
||||||
afx->crc = CRCINIT;
|
gcry_md_reset (afx->crc_md);
|
||||||
afx->idx = 0;
|
afx->idx = 0;
|
||||||
afx->radbuf[0] = 0;
|
afx->radbuf[0] = 0;
|
||||||
}
|
}
|
||||||
@ -768,7 +776,7 @@ fake_packet( armor_filter_context_t *afx, IOBUF a,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
afx->inp_checked = 1;
|
afx->inp_checked = 1;
|
||||||
afx->crc = CRCINIT;
|
gcry_md_reset (afx->crc_md);
|
||||||
afx->idx = 0;
|
afx->idx = 0;
|
||||||
afx->radbuf[0] = 0;
|
afx->radbuf[0] = 0;
|
||||||
}
|
}
|
||||||
@ -797,10 +805,8 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
|
|||||||
int checkcrc=0;
|
int checkcrc=0;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
int idx, i, onlypad=0;
|
int idx, onlypad=0;
|
||||||
u32 crc;
|
|
||||||
|
|
||||||
crc = afx->crc;
|
|
||||||
idx = afx->idx;
|
idx = afx->idx;
|
||||||
val = afx->radbuf[0];
|
val = afx->radbuf[0];
|
||||||
for( n=0; n < size; ) {
|
for( n=0; n < size; ) {
|
||||||
@ -881,14 +887,14 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
|
|||||||
idx = (idx+1) % 4;
|
idx = (idx+1) % 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i=0; i < n; i++ )
|
|
||||||
crc = (crc << 8) ^ crc_table[((crc >> 16)&0xff) ^ buf[i]];
|
|
||||||
crc &= 0x00ffffff;
|
|
||||||
afx->crc = crc;
|
|
||||||
afx->idx = idx;
|
afx->idx = idx;
|
||||||
afx->radbuf[0] = val;
|
afx->radbuf[0] = val;
|
||||||
|
|
||||||
|
if( n )
|
||||||
|
gcry_md_write (afx->crc_md, buf, n);
|
||||||
|
|
||||||
if( checkcrc ) {
|
if( checkcrc ) {
|
||||||
|
gcry_md_final (afx->crc_md);
|
||||||
afx->any_data = 1;
|
afx->any_data = 1;
|
||||||
afx->inp_checked=0;
|
afx->inp_checked=0;
|
||||||
afx->faked = 0;
|
afx->faked = 0;
|
||||||
@ -957,10 +963,10 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
|
|||||||
log_info(_("malformed CRC\n"));
|
log_info(_("malformed CRC\n"));
|
||||||
rc = invalid_crc();
|
rc = invalid_crc();
|
||||||
}
|
}
|
||||||
else if( mycrc != afx->crc ) {
|
else if( mycrc != get_afx_crc (afx) ) {
|
||||||
log_info (_("CRC error; %06lX - %06lX\n"),
|
log_info (_("CRC error; %06lX - %06lX\n"),
|
||||||
(ulong)afx->crc, (ulong)mycrc);
|
(ulong)get_afx_crc (afx), (ulong)mycrc);
|
||||||
rc = invalid_crc();
|
rc = invalid_crc();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rc = 0;
|
rc = 0;
|
||||||
@ -1188,18 +1194,15 @@ armor_filter( void *opaque, int control,
|
|||||||
afx->status++;
|
afx->status++;
|
||||||
afx->idx = 0;
|
afx->idx = 0;
|
||||||
afx->idx2 = 0;
|
afx->idx2 = 0;
|
||||||
afx->crc = CRCINIT;
|
gcry_md_reset (afx->crc_md);
|
||||||
|
|
||||||
}
|
}
|
||||||
crc = afx->crc;
|
|
||||||
idx = afx->idx;
|
idx = afx->idx;
|
||||||
idx2 = afx->idx2;
|
idx2 = afx->idx2;
|
||||||
for(i=0; i < idx; i++ )
|
for(i=0; i < idx; i++ )
|
||||||
radbuf[i] = afx->radbuf[i];
|
radbuf[i] = afx->radbuf[i];
|
||||||
|
|
||||||
for(i=0; i < size; i++ )
|
if( size )
|
||||||
crc = (crc << 8) ^ crc_table[((crc >> 16)&0xff) ^ buf[i]];
|
gcry_md_write (afx->crc_md, buf, size);
|
||||||
crc &= 0x00ffffff;
|
|
||||||
|
|
||||||
for( ; size; buf++, size-- ) {
|
for( ; size; buf++, size-- ) {
|
||||||
radbuf[idx++] = *buf;
|
radbuf[idx++] = *buf;
|
||||||
@ -1224,7 +1227,6 @@ armor_filter( void *opaque, int control,
|
|||||||
afx->radbuf[i] = radbuf[i];
|
afx->radbuf[i] = radbuf[i];
|
||||||
afx->idx = idx;
|
afx->idx = idx;
|
||||||
afx->idx2 = idx2;
|
afx->idx2 = idx2;
|
||||||
afx->crc = crc;
|
|
||||||
}
|
}
|
||||||
else if( control == IOBUFCTRL_INIT )
|
else if( control == IOBUFCTRL_INIT )
|
||||||
{
|
{
|
||||||
@ -1250,7 +1252,8 @@ armor_filter( void *opaque, int control,
|
|||||||
if( afx->cancel )
|
if( afx->cancel )
|
||||||
;
|
;
|
||||||
else if( afx->status ) { /* pad, write cecksum, and bottom line */
|
else if( afx->status ) { /* pad, write cecksum, and bottom line */
|
||||||
crc = afx->crc;
|
gcry_md_final (afx->crc_md);
|
||||||
|
crc = get_afx_crc (afx);
|
||||||
idx = afx->idx;
|
idx = afx->idx;
|
||||||
idx2 = afx->idx2;
|
idx2 = afx->idx2;
|
||||||
if( idx ) {
|
if( idx ) {
|
||||||
|
@ -61,7 +61,7 @@ typedef struct {
|
|||||||
|
|
||||||
byte radbuf[4];
|
byte radbuf[4];
|
||||||
int idx, idx2;
|
int idx, idx2;
|
||||||
u32 crc;
|
gcry_md_hd_t crc_md;
|
||||||
|
|
||||||
int status; /* an internal state flag */
|
int status; /* an internal state flag */
|
||||||
int cancel;
|
int cancel;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user