mirror of
https://salsa.debian.org/gnuk-team/gnuk/gnuk.git
synced 2024-09-20 02:40:08 +00:00
Compare commits
4 Commits
913ebf6f32
...
1fdfb90a29
Author | SHA1 | Date | |
---|---|---|---|
|
1fdfb90a29 | ||
|
de9652726b | ||
|
739f17781c | ||
|
60f62e1968 |
10
ChangeLog
10
ChangeLog
@ -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>
|
||||
|
||||
* src/modinv.c (modinv_normalize): Fix the computation.
|
||||
|
9
NEWS
9
NEWS
@ -3,11 +3,16 @@ Gnuk NEWS - User visible changes
|
||||
|
||||
* 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
|
||||
|
||||
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
|
||||
|
29
README
29
README
@ -1,14 +1,14 @@
|
||||
Gnuk - An Implementation of USB Cryptographic Token for GnuPG
|
||||
|
||||
Version 2.1
|
||||
2023-09-05
|
||||
Version 2.2
|
||||
2024-04-20
|
||||
Niibe Yutaka
|
||||
Free Software Initiative of Japan
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
on the original implementation by Dr. Brian Gladman. See:
|
||||
|
||||
http://brg.a2hosted.com//oldsite/cryptography_technology/sha/index.php
|
||||
(was at:
|
||||
http://gladman.plushost.co.uk/oldsite/cryptography_technology/sha/index.php)
|
||||
https://web.archive.org/web/20140314032610/http://gladman.plushost.co.uk/oldsite/cryptography_technology/sha/index.php
|
||||
|
||||
|
||||
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
|
||||
and its friends. I'm using:
|
||||
|
||||
binutils-arm-none-eabi 2.40-2+18+b1
|
||||
gcc-arm-none-eabi 15:12.2.rel1-1
|
||||
picolibc-arm-none-eabi 1.8-1
|
||||
gdb-multiarch 13.1-3
|
||||
|
||||
Or else, see https://launchpad.net/gcc-arm-embedded for preparation of
|
||||
GNU Toolchain for 'arm-none-eabi' target.
|
||||
binutils-arm-none-eabi 2.41.90.20240115-1+23
|
||||
gcc-arm-none-eabi 15:13.2.rel1-2
|
||||
picolibc-arm-none-eabi 1.8.6-2
|
||||
gdb-multiarch 13.2-1
|
||||
|
||||
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.
|
||||
|
||||
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"
|
||||
|
||||
|
||||
@ -338,7 +333,7 @@ How to protect flash ROM
|
||||
|
||||
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
|
||||
|
||||
After power-off / power-on sequence, the contents of flash ROM cannot
|
||||
@ -346,7 +341,7 @@ be accessible from JTAG debugger.
|
||||
|
||||
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
|
||||
|
||||
Upon unprotection, flash is erased.
|
||||
|
@ -13,7 +13,7 @@ CSRC = main.c \
|
||||
modp256k1.c jpc_p256k1.c ec_p256k1.c call-ec_p256k1.c \
|
||||
mod25638.c ecc-ed25519.c ecc-x25519.c sha512.c \
|
||||
p448.c ecc-x448.c \
|
||||
ecc-ed448.c shake256.c \
|
||||
ecc-ed448.c keccak.c \
|
||||
random.c neug.c sha256.c
|
||||
|
||||
INCDIR =
|
||||
|
@ -3,7 +3,7 @@
|
||||
* the twisted Edwards curve: -x^2 + y^2 = 1 + d*x^2*y^2
|
||||
* 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>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@ -41,7 +41,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "p448.h"
|
||||
#include "shake256.h"
|
||||
#include "keccak.h"
|
||||
|
||||
|
||||
#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)
|
||||
{
|
||||
bn448 a[1], k[1], s[1];
|
||||
shake_context ctx;
|
||||
keccak_context ctx;
|
||||
const unsigned char x_olen[2] = { 0, 0 };
|
||||
uint32_t hash[BN912_WORDS];
|
||||
uint8_t r[57];
|
||||
|
@ -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>
|
||||
*
|
||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||
@ -17,7 +17,7 @@
|
||||
* License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define SHAKE_BITS 256
|
||||
#define SHAKE_INDEX_MAX (200 - (SHAKE_BITS >> 2))
|
||||
#define INDEX_MAX(cap) (200 - (cap >> 3))
|
||||
|
||||
#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
|
||||
@ -43,7 +60,8 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "shake256.h"
|
||||
#include <stdarg.h>
|
||||
#include "keccak.h"
|
||||
|
||||
/* Round constants in iota step. */
|
||||
static const uint64_t rc[24] = {
|
||||
@ -144,59 +162,128 @@ keccak_f1600 (uint64_t s[25])
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
shake256_start (struct shake_context *shake)
|
||||
{
|
||||
memset (shake, 0, sizeof (shake_context));
|
||||
}
|
||||
|
||||
void
|
||||
shake256_update (struct shake_context *shake,
|
||||
const unsigned char *src, unsigned int size)
|
||||
static void
|
||||
keccak_update (struct keccak_context *keccak,
|
||||
const unsigned char *src, unsigned int size)
|
||||
{
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
while (1)
|
||||
{
|
||||
absorb (shake->state, shake->index, *src++);
|
||||
if (++shake->index == SHAKE_INDEX_MAX)
|
||||
absorb (keccak->state, keccak->index, *src++);
|
||||
if (++keccak->index == keccak->index_max)
|
||||
{
|
||||
keccak_f1600 (shake->state);
|
||||
shake->index = 0;
|
||||
keccak_f1600 (keccak->state);
|
||||
keccak->index = 0;
|
||||
}
|
||||
if (--size == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
shake256_finish (struct shake_context *shake,
|
||||
unsigned char *dst, unsigned int size)
|
||||
static void
|
||||
keccak_finish (struct keccak_context *keccak,
|
||||
unsigned char *dst, unsigned int size, uint8_t suffix)
|
||||
{
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
absorb (shake->state, shake->index, 0x1F);
|
||||
absorb (shake->state, SHAKE_INDEX_MAX - 1, 0x80);
|
||||
keccak_f1600 (shake->state);
|
||||
shake->index = 0;
|
||||
absorb (keccak->state, keccak->index, suffix);
|
||||
absorb (keccak->state, keccak->index_max - 1, 0x80);
|
||||
keccak_f1600 (keccak->state);
|
||||
keccak->index = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
*dst++ = squeeze (shake->state, shake->index);
|
||||
*dst++ = squeeze (keccak->state, keccak->index);
|
||||
if (--size == 0)
|
||||
break;
|
||||
if (++shake->index == SHAKE_INDEX_MAX)
|
||||
if (++keccak->index == keccak->index_max)
|
||||
{
|
||||
keccak_f1600 (shake->state);
|
||||
shake->index = 0;
|
||||
keccak_f1600 (keccak->state);
|
||||
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
24
src/keccak.h
Normal 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);
|
@ -2,7 +2,7 @@
|
||||
* openpgp-do.c -- OpenPGP card Data Objects (DO) handling
|
||||
*
|
||||
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018,
|
||||
* 2020, 2021, 2022
|
||||
* 2020, 2021, 2022, 2024
|
||||
* Free Software Initiative of Japan
|
||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||
*
|
||||
@ -34,7 +34,7 @@
|
||||
#include "random.h"
|
||||
#include "aes.h"
|
||||
#include "sha512.h"
|
||||
#include "shake256.h"
|
||||
#include "keccak.h"
|
||||
|
||||
/* Forward declaration */
|
||||
#define CLEAN_PAGE_FULL 1
|
||||
@ -1567,7 +1567,7 @@ proc_key_import (const uint8_t *data, int len)
|
||||
}
|
||||
else if (attr == ALGO_ED448)
|
||||
{
|
||||
shake_context ctx;
|
||||
keccak_context ctx;
|
||||
uint8_t hash[128];
|
||||
|
||||
if (len - 12 != 57)
|
||||
@ -2348,7 +2348,7 @@ gpg_do_keygen (uint8_t *buf)
|
||||
}
|
||||
else if (attr == ALGO_ED448)
|
||||
{
|
||||
shake_context ctx;
|
||||
keccak_context ctx;
|
||||
rnd = random_bytes_get ();
|
||||
shake256_start (&ctx);
|
||||
shake256_update (&ctx, rnd, 32);
|
||||
|
@ -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);
|
@ -1689,12 +1689,14 @@ ccid_thread (void *arg)
|
||||
struct ep_out *epo = &endpoint_out;
|
||||
struct apdu *a = &apdu;
|
||||
|
||||
#ifdef ACKBTN_SUPPORT
|
||||
if (ackbtn_active)
|
||||
{
|
||||
ackbtn_active = 0;
|
||||
ackbtn_disable ();
|
||||
led_blink (LED_WAIT_FOR_BUTTON);
|
||||
}
|
||||
#endif
|
||||
|
||||
epi_init (epi, ENDP1, c);
|
||||
epo_init (epo, ENDP1, c);
|
||||
@ -1797,9 +1799,7 @@ ccid_thread (void *arg)
|
||||
else if (m == EV_EXEC_FINISHED)
|
||||
if (c->ccid_state == CCID_STATE_EXECUTE)
|
||||
{
|
||||
#ifdef ACKBTN_SUPPORT
|
||||
exec_done:
|
||||
#endif
|
||||
if (c->a->sw == GPG_THREAD_TERMINATED)
|
||||
{
|
||||
c->sw1sw2[0] = 0x90;
|
||||
@ -1868,8 +1868,10 @@ ccid_thread (void *arg)
|
||||
if (c->timeout_cnt == 7
|
||||
&& c->ccid_state == CCID_STATE_ACK_REQUIRED_1)
|
||||
{
|
||||
#ifdef ACKBTN_SUPPORT
|
||||
ackbtn_active = 0;
|
||||
ackbtn_disable ();
|
||||
#endif
|
||||
led_blink (LED_WAIT_FOR_BUTTON);
|
||||
c->a->sw = GPG_ACK_TIMEOUT;
|
||||
c->a->res_apdu_data_len = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user