Compare commits

...

4 Commits

Author SHA1 Message Date
Lovro Orešković
592b835ff1 Merge branch 'patch-1' into 'master'
Initial docker build fix

See merge request gnuk-team/gnuk/gnuk!1
2024-04-27 20:51:54 +00:00
NIIBE Yutaka
de9652726b
Version 2.2.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2024-04-20 11:20:40 +09:00
NIIBE Yutaka
739f17781c
keccak.c also provides SHA-3 and SHAKE128.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2024-04-18 14:09:57 +09:00
Lovro Orešković
d243e64856 Update Dockerfile.release 2018-04-18 14:32:41 +00:00
11 changed files with 186 additions and 78 deletions

View File

@ -1,3 +1,13 @@
2024-04-20 NIIBE Yutaka <gniibe@fsij.org>
* VERSION: Version 2.2.
2024-04-18 NIIBE Yutaka <gniibe@fsij.org>
* src/keccak.c, src/keccak.h: Rename. Also offer SHA-3.
* src/ecc-ed448.c (ed448_sign): Use keccak_context.
* src/openpgp-do.c (proc_key_import, gpg_do_keygen): Likewise.
2024-02-02 NIIBE Yutaka <gniibe@fsij.org> 2024-02-02 NIIBE Yutaka <gniibe@fsij.org>
* src/modinv.c (modinv_normalize): Fix the computation. * src/modinv.c (modinv_normalize): Fix the computation.

9
NEWS
View File

@ -3,11 +3,16 @@ Gnuk NEWS - User visible changes
* Major changes in Gnuk 2.2 * Major changes in Gnuk 2.2
Released 202?-??-??, by NIIBE Yutaka Released 2024-04-20, by NIIBE Yutaka
** Modular inverse by safegcd256 for Ed25519 and X25519 computation ** Modular inverse by safegcd256 for Ed25519 and X25519 computation
Ed25519 and X25519 computation are now faster with safegcd256. Ed25519 and X25519 computation are now a bit faster with safegcd256.
** X25519 with 2^25.5 limb
X25519 computation is done with 2^25.5 limb. It may be better on
other MCUs.
* Major changes in Gnuk 2.1 * Major changes in Gnuk 2.1

29
README
View File

@ -1,14 +1,14 @@
Gnuk - An Implementation of USB Cryptographic Token for GnuPG Gnuk - An Implementation of USB Cryptographic Token for GnuPG
Version 2.1 Version 2.2
2023-09-05 2024-04-20
Niibe Yutaka Niibe Yutaka
Free Software Initiative of Japan Free Software Initiative of Japan
Release Notes Release Notes
============= =============
This is the release of Gnuk, version 2.1, which has major clean up This is the release of Gnuk, version 2.2, which has major clean up
from Gnuk 1.2. Many (questionable) features have been removed. from Gnuk 1.2. Many (questionable) features have been removed.
It has supports of Ed25519 and X25519 (ECDH on Curve25519). It also It has supports of Ed25519 and X25519 (ECDH on Curve25519). It also
@ -161,9 +161,7 @@ Gnuk source code is under src/ directory.
Note that SHA-2 hash function implementation, src/sha256.c, is based Note that SHA-2 hash function implementation, src/sha256.c, is based
on the original implementation by Dr. Brian Gladman. See: on the original implementation by Dr. Brian Gladman. See:
http://brg.a2hosted.com//oldsite/cryptography_technology/sha/index.php https://web.archive.org/web/20140314032610/http://gladman.plushost.co.uk/oldsite/cryptography_technology/sha/index.php
(was at:
http://gladman.plushost.co.uk/oldsite/cryptography_technology/sha/index.php)
License License
@ -257,13 +255,10 @@ You need GNU toolchain and newlib for 'arm-none-eabi' target.
On Debian we can install the packages of gcc-arm-none-eabi On Debian we can install the packages of gcc-arm-none-eabi
and its friends. I'm using: and its friends. I'm using:
binutils-arm-none-eabi 2.40-2+18+b1 binutils-arm-none-eabi 2.41.90.20240115-1+23
gcc-arm-none-eabi 15:12.2.rel1-1 gcc-arm-none-eabi 15:13.2.rel1-2
picolibc-arm-none-eabi 1.8-1 picolibc-arm-none-eabi 1.8.6-2
gdb-multiarch 13.1-3 gdb-multiarch 13.2-1
Or else, see https://launchpad.net/gcc-arm-embedded for preparation of
GNU Toolchain for 'arm-none-eabi' target.
Change directory to `src': Change directory to `src':
@ -312,9 +307,9 @@ Flying Stone Tiny 01
If you are using Flying Stone Tiny 01, you need a SWD writer. If you are using Flying Stone Tiny 01, you need a SWD writer.
OpenOCD 0.9.0 now supports ST-Link/V2. We can use it like: OpenOCD 0.12.0 supports ST-Link/V2. We can use it like:
$ openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg \ $ openocd -f interface/stlink.cfg -f target/stm32f1x.cfg \
-c "program build/gnuk.elf verify reset exit" -c "program build/gnuk.elf verify reset exit"
@ -338,7 +333,7 @@ How to protect flash ROM
To protect, invoke OpenOCD like (for FST-01): To protect, invoke OpenOCD like (for FST-01):
$ openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg \ $ openocd -f interface/stlink.cfg -f target/stm32f1x.cfg \
-c init -c "reset halt" -c "stm32f1x lock 0" -c reset -c exit -c init -c "reset halt" -c "stm32f1x lock 0" -c reset -c exit
After power-off / power-on sequence, the contents of flash ROM cannot After power-off / power-on sequence, the contents of flash ROM cannot
@ -346,7 +341,7 @@ be accessible from JTAG debugger.
Unprotecting is: Unprotecting is:
$ openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg \ $ openocd -f interface/stlink.cfg -f target/stm32f1x.cfg \
-c init -c "reset halt" -c "stm32f1x unlock 0" -c reset -c exit -c init -c "reset halt" -c "stm32f1x unlock 0" -c reset -c exit
Upon unprotection, flash is erased. Upon unprotection, flash is erased.

View File

@ -1 +1 @@
release/2.1 release/2.2

View File

@ -3,4 +3,4 @@ LABEL Description="Image for building gnuK"
RUN apt update -y && apt install -y make gcc-arm-none-eabi && apt clean RUN apt update -y && apt install -y make gcc-arm-none-eabi && apt clean
CMD ["/bin/sh", "-c", "cd /gnuk/src && make clean && ./configure $GNUK_CONFIG && make"] CMD ["/bin/sh", "-c", "cd /gnuk/src && ./configure $GNUK_CONFIG && make"]

View File

@ -13,7 +13,7 @@ CSRC = main.c \
modp256k1.c jpc_p256k1.c ec_p256k1.c call-ec_p256k1.c \ modp256k1.c jpc_p256k1.c ec_p256k1.c call-ec_p256k1.c \
mod25638.c ecc-ed25519.c ecc-x25519.c sha512.c \ mod25638.c ecc-ed25519.c ecc-x25519.c sha512.c \
p448.c ecc-x448.c \ p448.c ecc-x448.c \
ecc-ed448.c shake256.c \ ecc-ed448.c keccak.c \
random.c neug.c sha256.c random.c neug.c sha256.c
INCDIR = INCDIR =

View File

@ -3,7 +3,7 @@
* the twisted Edwards curve: -x^2 + y^2 = 1 + d*x^2*y^2 * the twisted Edwards curve: -x^2 + y^2 = 1 + d*x^2*y^2
* d = -39081 * d = -39081
* *
* Copyright (C) 2021 Free Software Initiative of Japan * Copyright (C) 2021, 2024 Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org> * Author: NIIBE Yutaka <gniibe@fsij.org>
* *
* This file is a part of Gnuk, a GnuPG USB Token implementation. * This file is a part of Gnuk, a GnuPG USB Token implementation.
@ -41,7 +41,7 @@
#include <string.h> #include <string.h>
#include "p448.h" #include "p448.h"
#include "shake256.h" #include "keccak.h"
#define C_WORDS 7 #define C_WORDS 7
@ -761,7 +761,7 @@ ed448_sign (uint8_t *out, const uint8_t *input, unsigned int ilen,
const uint8_t *a_in, const uint8_t *seed, const uint8_t *pk) const uint8_t *a_in, const uint8_t *seed, const uint8_t *pk)
{ {
bn448 a[1], k[1], s[1]; bn448 a[1], k[1], s[1];
shake_context ctx; keccak_context ctx;
const unsigned char x_olen[2] = { 0, 0 }; const unsigned char x_olen[2] = { 0, 0 };
uint32_t hash[BN912_WORDS]; uint32_t hash[BN912_WORDS];
uint8_t r[57]; uint8_t r[57];

View File

@ -1,7 +1,7 @@
/* /*
* shake256.c -- Compute SHAKE hash. * keccak.c -- Compute Keccak hash.
* *
* Copyright (C) 2021 Free Software Initiative of Japan * Copyright (C) 2021, 2024 Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org> * Author: NIIBE Yutaka <gniibe@fsij.org>
* *
* This file is a part of Gnuk, a GnuPG USB Token implementation. * This file is a part of Gnuk, a GnuPG USB Token implementation.
@ -17,7 +17,7 @@
* License for more details. * License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -29,8 +29,25 @@
* August 2015. * August 2015.
*/ */
#define SHAKE_BITS 256 #define INDEX_MAX(cap) (200 - (cap >> 3))
#define SHAKE_INDEX_MAX (200 - (SHAKE_BITS >> 2))
#define SHAKE256_CAPACITY 512
#define SHAKE256_INDEX_MAX INDEX_MAX (SHAKE256_CAPACITY)
#define SHAKE128_CAPACITY 256
#define SHAKE128_INDEX_MAX INDEX_MAX (SHAKE128_CAPACITY)
#define SHA3_512_CAPACITY 1024
#define SHA3_512_INDEX_MAX INDEX_MAX (SHA3_512_CAPACITY)
/*
* SHAKE is defined appending 11 at the end to RawSHAKE,
* RawSHAKE is defined adding 11 at the end to KECCAK,
* and KECCACK uses pad10*1 at the end.
* This means adding 111110*1 at the end.
*/
#define SHAKE_SUFFIX 0x1F
#define SHA3_SUFFIX 0x06
/* /*
* b=1600 * b=1600
@ -43,7 +60,8 @@
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include "shake256.h" #include <stdarg.h>
#include "keccak.h"
/* Round constants in iota step. */ /* Round constants in iota step. */
static const uint64_t rc[24] = { static const uint64_t rc[24] = {
@ -144,59 +162,128 @@ keccak_f1600 (uint64_t s[25])
} }
} }
void static void
shake256_start (struct shake_context *shake) keccak_update (struct keccak_context *keccak,
{ const unsigned char *src, unsigned int size)
memset (shake, 0, sizeof (shake_context));
}
void
shake256_update (struct shake_context *shake,
const unsigned char *src, unsigned int size)
{ {
if (size == 0) if (size == 0)
return; return;
while (1) while (1)
{ {
absorb (shake->state, shake->index, *src++); absorb (keccak->state, keccak->index, *src++);
if (++shake->index == SHAKE_INDEX_MAX) if (++keccak->index == keccak->index_max)
{ {
keccak_f1600 (shake->state); keccak_f1600 (keccak->state);
shake->index = 0; keccak->index = 0;
} }
if (--size == 0) if (--size == 0)
break; break;
} }
} }
void static void
shake256_finish (struct shake_context *shake, keccak_finish (struct keccak_context *keccak,
unsigned char *dst, unsigned int size) unsigned char *dst, unsigned int size, uint8_t suffix)
{ {
if (size == 0) if (size == 0)
return; return;
/* absorb (keccak->state, keccak->index, suffix);
* SHAKE is defined appending 11 at the end to RawSHAKE, absorb (keccak->state, keccak->index_max - 1, 0x80);
* RawSHAKE is defined adding 11 at the end to KECCAK, keccak_f1600 (keccak->state);
* and KECCACK uses pad10*1 at the end. keccak->index = 0;
* This means adding 111110*1 at the end.
*/
absorb (shake->state, shake->index, 0x1F);
absorb (shake->state, SHAKE_INDEX_MAX - 1, 0x80);
keccak_f1600 (shake->state);
shake->index = 0;
while (1) while (1)
{ {
*dst++ = squeeze (shake->state, shake->index); *dst++ = squeeze (keccak->state, keccak->index);
if (--size == 0) if (--size == 0)
break; break;
if (++shake->index == SHAKE_INDEX_MAX) if (++keccak->index == keccak->index_max)
{ {
keccak_f1600 (shake->state); keccak_f1600 (keccak->state);
shake->index = 0; keccak->index = 0;
} }
} }
} }
void
shake128_start (struct keccak_context *shake)
{
memset (shake, 0, sizeof (keccak_context));
shake->index_max = SHAKE128_INDEX_MAX;
}
void
shake256_start (struct keccak_context *shake)
{
memset (shake, 0, sizeof (keccak_context));
shake->index_max = SHAKE256_INDEX_MAX;
}
void
shake128_update (struct keccak_context *shake,
const unsigned char *src, unsigned int size)
{
keccak_update (shake, src, size);
}
void
shake256_update (struct keccak_context *shake,
const unsigned char *src, unsigned int size)
{
keccak_update (shake, src, size);
}
void
shake128_finish (struct keccak_context *shake,
unsigned char *dst, unsigned int size)
{
keccak_finish (shake, dst, size, SHAKE_SUFFIX);
}
void
shake256_finish (struct keccak_context *shake,
unsigned char *dst, unsigned int size)
{
keccak_finish (shake, dst, size, SHAKE_SUFFIX);
}
void
shake256v (uint8_t *out, size_t outlen, ...)
{
struct keccak_context ctx;
va_list ap;
void *p;
size_t len;
shake256_start (&ctx);
va_start (ap, outlen);
while (1)
{
p = va_arg (ap, void *);
len = va_arg (ap, size_t);
if (!p)
break;
shake256_update (&ctx, p, len);
}
va_end (ap);
shake256_finish (&ctx, out, outlen);
}
void
sha3_512 (uint8_t h[64], const uint8_t *in, size_t inlen)
{
struct keccak_context ctx;
memset (&ctx, 0, sizeof (keccak_context));
ctx.index_max = SHA3_512_INDEX_MAX;
keccak_update (&ctx, in, inlen);
keccak_finish (&ctx, h, 64, SHA3_SUFFIX);
}

24
src/keccak.h Normal file
View File

@ -0,0 +1,24 @@
#include <stdint.h>
struct keccak_context {
uint64_t state[25];
uint32_t index : 8;
uint32_t index_max : 8;
};
typedef struct keccak_context keccak_context;
void shake128_start (struct keccak_context *keccak);
void shake128_update (struct keccak_context *keccak,
const unsigned char *src, unsigned int size);
void shake128_finish (struct keccak_context *keccak,
unsigned char *dst, unsigned int size);
void shake256_start (struct keccak_context *keccak);
void shake256_update (struct keccak_context *keccak,
const unsigned char *src, unsigned int size);
void shake256_finish (struct keccak_context *keccak,
unsigned char *dst, unsigned int size);
void shake256v (uint8_t *out, size_t outlen, ...);
void sha3_512 (uint8_t h[64], const uint8_t *in, size_t inlen);

View File

@ -2,7 +2,7 @@
* openpgp-do.c -- OpenPGP card Data Objects (DO) handling * openpgp-do.c -- OpenPGP card Data Objects (DO) handling
* *
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, * Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018,
* 2020, 2021, 2022 * 2020, 2021, 2022, 2024
* Free Software Initiative of Japan * Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org> * Author: NIIBE Yutaka <gniibe@fsij.org>
* *
@ -34,7 +34,7 @@
#include "random.h" #include "random.h"
#include "aes.h" #include "aes.h"
#include "sha512.h" #include "sha512.h"
#include "shake256.h" #include "keccak.h"
/* Forward declaration */ /* Forward declaration */
#define CLEAN_PAGE_FULL 1 #define CLEAN_PAGE_FULL 1
@ -1567,7 +1567,7 @@ proc_key_import (const uint8_t *data, int len)
} }
else if (attr == ALGO_ED448) else if (attr == ALGO_ED448)
{ {
shake_context ctx; keccak_context ctx;
uint8_t hash[128]; uint8_t hash[128];
if (len - 12 != 57) if (len - 12 != 57)
@ -2348,7 +2348,7 @@ gpg_do_keygen (uint8_t *buf)
} }
else if (attr == ALGO_ED448) else if (attr == ALGO_ED448)
{ {
shake_context ctx; keccak_context ctx;
rnd = random_bytes_get (); rnd = random_bytes_get ();
shake256_start (&ctx); shake256_start (&ctx);
shake256_update (&ctx, rnd, 32); shake256_update (&ctx, rnd, 32);

View File

@ -1,13 +0,0 @@
#include <stdint.h>
struct shake_context {
uint64_t state[25];
uint32_t index;
};
typedef struct shake_context shake_context;
void shake256_start (struct shake_context *shake);
void shake256_update (struct shake_context *shake,
const unsigned char *src, unsigned int size);
void shake256_finish (struct shake_context *shake,
unsigned char *dst, unsigned int size);