Add kdf_calc.py.
This commit is contained in:
13
NEWS
13
NEWS
@@ -1,5 +1,18 @@
|
|||||||
Gnuk NEWS - User visible changes
|
Gnuk NEWS - User visible changes
|
||||||
|
|
||||||
|
* Major changes in Gnuk 1.2.9
|
||||||
|
|
||||||
|
Released 2018-03-31, by NIIBE Yutaka
|
||||||
|
|
||||||
|
** Add "single-salt" support for KDF-DO
|
||||||
|
With KDF-DO, "admin-less" mode didn't work well. With new feature of
|
||||||
|
"single-salt" support, we can use "admin-less" mode with KDF-DO.
|
||||||
|
|
||||||
|
** factory-reset deletes all upgrade public keys
|
||||||
|
By card-edit/factory-reset by GnuPG, it deletes all upgrade public
|
||||||
|
keys, now.
|
||||||
|
|
||||||
|
|
||||||
* Major changes in Gnuk 1.2.8
|
* Major changes in Gnuk 1.2.8
|
||||||
|
|
||||||
Released 2018-01-23, by NIIBE Yutaka
|
Released 2018-01-23, by NIIBE Yutaka
|
||||||
|
|||||||
10
README
10
README
@@ -1,14 +1,14 @@
|
|||||||
Gnuk - An Implementation of USB Cryptographic Token for GnuPG
|
Gnuk - An Implementation of USB Cryptographic Token for GnuPG
|
||||||
|
|
||||||
Version 1.2.8
|
Version 1.2.9
|
||||||
2018-01-23
|
2018-03-31
|
||||||
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 1.2.8, which has major
|
This is the release of Gnuk, version 1.2.9, which has major
|
||||||
incompatible changes to Gnuk 1.0.x. Specifically, it now supports
|
incompatible changes to Gnuk 1.0.x. Specifically, it now supports
|
||||||
overriding key import, but importing keys (or generating keys) results
|
overriding key import, but importing keys (or generating keys) results
|
||||||
password reset. Also, you need to import private keys before changing
|
password reset. Also, you need to import private keys before changing
|
||||||
@@ -25,9 +25,9 @@ than 8 seconds to sign/decrypt. Key generation of RSA-4096 just fails,
|
|||||||
because the device doesn't have enough memory.
|
because the device doesn't have enough memory.
|
||||||
|
|
||||||
It supports new KDF-DO feature. To use the feature, you need to use
|
It supports new KDF-DO feature. To use the feature, you need to use
|
||||||
newer GnuPG (forthcoming 2.2.5 or later). And you need to manually
|
newer GnuPG (forthcoming 2.2.6 or later). And you need to manually
|
||||||
prepare the KDF-DO on your token. Please note that this is
|
prepare the KDF-DO on your token. Please note that this is
|
||||||
experimental. Better way to prepare KDF-DO will be expected.
|
experimental. GnuPG 2.2.6 will include KDF-DO setup.
|
||||||
|
|
||||||
|
|
||||||
What's Gnuk?
|
What's Gnuk?
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
"""
|
"""
|
||||||
gnuk_token.py - a library for Gnuk Token
|
gnuk_token.py - a library for Gnuk Token
|
||||||
|
|
||||||
Copyright (C) 2011, 2012, 2013, 2015, 2017
|
Copyright (C) 2011, 2012, 2013, 2015, 2017, 2018
|
||||||
Free Software Initiative of Japan
|
Free Software Initiative of Japan
|
||||||
Author: NIIBE Yutaka <gniibe@fsij.org>
|
Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
@@ -635,3 +635,48 @@ def UNSIGNED(n):
|
|||||||
def crc32(bytestr):
|
def crc32(bytestr):
|
||||||
crc = binascii.crc32(bytestr)
|
crc = binascii.crc32(bytestr)
|
||||||
return UNSIGNED(crc)
|
return UNSIGNED(crc)
|
||||||
|
|
||||||
|
def parse_kdf_data(kdf_data):
|
||||||
|
if len(kdf_data) == 90:
|
||||||
|
single_salt = True
|
||||||
|
elif len(kdf_data) == 110:
|
||||||
|
single_salt = False
|
||||||
|
else:
|
||||||
|
raise ValueError("length does not much")
|
||||||
|
|
||||||
|
if kdf_data[0:2] != b'\x81\x01':
|
||||||
|
raise ValueError("data does not much")
|
||||||
|
algo = kdf_data[2]
|
||||||
|
if kdf_data[3:5] != b'\x82\x01':
|
||||||
|
raise ValueError("data does not much")
|
||||||
|
subalgo = kdf_data[5]
|
||||||
|
if kdf_data[6:8] != b'\x83\x04':
|
||||||
|
raise ValueError("data does not much")
|
||||||
|
iters = unpack(">I", kdf_data[8:12])[0]
|
||||||
|
if kdf_data[12:14] != b'\x84\x08':
|
||||||
|
raise ValueError("data does not much")
|
||||||
|
salt = kdf_data[14:22]
|
||||||
|
if single_salt:
|
||||||
|
salt_reset = None
|
||||||
|
salt_admin = None
|
||||||
|
if kdf_data[22:24] != b'\x87\x20':
|
||||||
|
raise ValueError("data does not much")
|
||||||
|
hash_user = kdf_data[24:56]
|
||||||
|
if kdf_data[56:58] != b'\x88\x20':
|
||||||
|
raise ValueError("data does not much")
|
||||||
|
hash_admin = kdf_data[58:90]
|
||||||
|
else:
|
||||||
|
if kdf_data[22:24] != b'\x85\x08':
|
||||||
|
raise ValueError("data does not much")
|
||||||
|
salt_reset = kdf_data[24:32]
|
||||||
|
if kdf_data[32:34] != b'\x86\x08':
|
||||||
|
raise ValueError("data does not much")
|
||||||
|
salt_admin = kdf_data[34:42]
|
||||||
|
if kdf_data[42:44] != b'\x87\x20':
|
||||||
|
raise ValueError("data does not much")
|
||||||
|
hash_user = kdf_data[44:76]
|
||||||
|
if kdf_data[76:78] != b'\x88\x20':
|
||||||
|
raise ValueError("data does not much")
|
||||||
|
hash_admin = kdf_data[78:110]
|
||||||
|
return ( algo, subalgo, iters, salt, salt_reset, salt_admin,
|
||||||
|
hash_user, hash_admin )
|
||||||
|
|||||||
47
tool/kdf_calc.py
Normal file
47
tool/kdf_calc.py
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
"""
|
||||||
|
kdf_calc.py - a library for calculating hash by KDF
|
||||||
|
|
||||||
|
Copyright (C) 2018 Free Software Initiative of Japan
|
||||||
|
Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||||
|
|
||||||
|
Gnuk is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Gnuk is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
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/>.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from cffi import FFI
|
||||||
|
|
||||||
|
DEF_gcry_kdf_derive="""
|
||||||
|
typedef unsigned int gpg_error_t;
|
||||||
|
gpg_error_t gcry_kdf_derive (const void *passphrase, size_t passphraselen,
|
||||||
|
int algo, int subalgo, const void *salt,
|
||||||
|
size_t saltlen, unsigned long iterations,
|
||||||
|
size_t keysize, void *keybuffer);
|
||||||
|
"""
|
||||||
|
|
||||||
|
GCRY_KDF_ITERSALTED_S2K = 19
|
||||||
|
GCRY_MD_SHA256 = 8
|
||||||
|
|
||||||
|
def kdf_calc(pw_string, salt_byte, iterations):
|
||||||
|
ffi = FFI()
|
||||||
|
ffi.cdef(DEF_gcry_kdf_derive)
|
||||||
|
libgcrypt = ffi.dlopen("libgcrypt.so")
|
||||||
|
pw=ffi.new("char []", pw_string.encode('UTF-8'))
|
||||||
|
salt = ffi.new("char []", salt_byte)
|
||||||
|
kb = ffi.new("char []", 32)
|
||||||
|
r = libgcrypt.gcry_kdf_derive(pw, len(pw_string), GCRY_KDF_ITERSALTED_S2K,
|
||||||
|
GCRY_MD_SHA256, salt, 8, iterations, 32, kb)
|
||||||
|
if r != 0:
|
||||||
|
raise ValueError("libgcrypt error", r)
|
||||||
|
return ffi.string(kb)
|
||||||
Reference in New Issue
Block a user