From gniibe at fsij.org Tue May 14 04:00:00 2019 From: gniibe at fsij.org (NIIBE Yutaka) Date: Tue, 14 May 2019 11:00:00 +0900 Subject: Chopstx 1.15 Message-ID: <87imud7q3j.fsf@iwagami.gniibe.org> Hello, Chopstx 1.15 is released. tag release/1.15 Tagger: NIIBE Yutaka Date: Tue May 14 10:31:58 2019 +0900 commit 4f46af7557c7bc0e4dfca756dd93e2ad8c0d9871 Change are: * Cortex-M4 support Cortex-M4 support has been added. Not supporting use of FPU or DSP, yet. Note that it's not intend to be used by Gnuk. * STM32L432 support USART and USB drivers are added. * New board support: ST Nucleo-32 L432 ST Nucleo-32 L432 is a small board with ST-Link/V2-1. * Minor implementation change: chopstx_claim_irq If the interrupt is disabled (possibly by chx_intr) when chopstx_claim_irq is called, INTR->ready is set to 1. This allows calling chopstx_claim_irq after hardware initialization which may cause an interrupt before the call of chopstx_claim_irq. and then, changes for USB: * SYS version 4.0 USB initialization/finalization API has been changed. SYS routines only handle USB cable configuration when supported by a board. * USB driver change Enabling/disabling USB module is done by USB driver. It's responsibility of board configuration to enable external transistor for pull-up D+-line by board/*.h. For all boards, USB driver doesn't use usb_lld_sys_init or usb_lld_sys_shutdown (those routines only can be used for USB self powered system, which Chopstx does not support yet). * Board configuration change For USB driver change, board-maple-mini.h, board-olimex-stm32-h103.h, board-stbee.h, and board-stm32-primer2.h were changed. Pull-up is enabled at the time of gpio_init. After ten years of experience, by comparing a board of STM32L432, I finally understand the exact reason (and confusion) why some boards of STM32F103 have a transistor to pull-up D+ line of USB. It is required to conform the USB specification not driving D+ line at start when a board runs in self-powered mode. And it can be used (for both of self-powered and bus-powered) to disconnect USB from device side. The latter can be done by other method, making SE0 state (by driving both of D+ line and D- line to GND). So, it is OK for bus-powered system to have fixed pull-up resistor on D+ line. Since modern MCU like STM32L432 has internal pull-up resistor support, there is no difference among boards. * * * I ported Chopstx to STM32L432, because of this: Tian Tian Xiang Shang - Another Hardware: https://www.gniibe.org/memo/development/ttxs/ttxs-hardware-another.html Version 0.0 of Tian Tian Xiang Shang (a smartcard reader implementation) is avaiable at: https://git.gniibe.org/gitweb/?p=chopstx/ttxs.git;a=summary -- From gniibe at fsij.org Thu May 23 01:50:58 2019 From: gniibe at fsij.org (NIIBE Yutaka) Date: Thu, 23 May 2019 08:50:58 +0900 Subject: Chopstx 1.16 and TTXS 0.1 In-Reply-To: <87imud7q3j.fsf@iwagami.gniibe.org> References: <87imud7q3j.fsf@iwagami.gniibe.org> Message-ID: <87muje59r1.fsf@iwagami.gniibe.org> Hello, Chopstx 1.16 is released (with forgotten update of README). tag release/1.16 Tagger: NIIBE Yutaka Date: Wed May 22 14:22:58 2019 +0900 commit d4ba52b0d130b19776828a65dad04301c9452997 It has a fix for USART driver of STM32L432, and change is only: * New board support: Gnukey-DS It is contributed by Evangelos Rigas. Thanks to Evangelos Rigas for the support. Version 0.1 of Tian Tian Xiang Shang (a smartcard reader implementation) is also avaiable at: https://git.gniibe.org/gitweb/?p=chopstx/ttxs.git;a=summary It now supports CCID protocol on serial line. * * * Those releases are done to prepare a copy of git.gniibe.org. Started in 2015, I have a practice selling the copy (to people in Japan): https://www.gniibe.org/shop/git-gniibe-org-copy.html I don't think there is any demand actually (in terms of business), but the existence of this service would be useful when a person does distribution of hardware devices. -- From simon at josefsson.org Tue May 28 10:16:42 2019 From: simon at josefsson.org (Simon Josefsson) Date: Tue, 28 May 2019 10:16:42 +0200 Subject: Gnuk Extractor In-Reply-To: References: <20190430154520.GC2295@pc21.mareichelt.com> Message-ID: <1559031402.27542.2.camel@josefsson.org> On Tue, 2019-04-30 at 19:45 +0100, Gary wrote: > On 30/04/2019 16:45, Markus Reichelt wrote: > > Hi, > > > > today I found out about Gnuk Extractor: > > > > https://github.com/rot42/gnuk-extractor > > > > Quoting the site: "This tool can extract the PGP secret keys from > > the > > dumped firmware of a Gnuk token.??It was tested on a Nitrokey Start > > and on a Gnuk Token made from a $2 ST-LINK/V2 clone." > > > > This relies on your flash not being locked after uploading > firmware/keys. > > If you lock the device using "stm32flx lock 0" via an openocd telnet > session, this should no longer be possible. Alternatively see the > "Lock > flash ROM" section of > > https://www.gniibe.org/memo/development/gnuk/gnuk-installation-to- > stm32-part-of-stm8s-discovery-kit.html Does this apply to the FST-01, FST-01G, or FST-01SZ? Does it depend on how Gnuk was installed on the device? How would I protect them? /Simon -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 228 bytes Desc: This is a digitally signed message part URL: From gniibe at fsij.org Wed May 29 02:59:33 2019 From: gniibe at fsij.org (NIIBE Yutaka) Date: Wed, 29 May 2019 09:59:33 +0900 Subject: Gnuk Extractor In-Reply-To: <1559031402.27542.2.camel@josefsson.org> References: <20190430154520.GC2295@pc21.mareichelt.com> <1559031402.27542.2.camel@josefsson.org> Message-ID: <871s0ihy8a.fsf@iwagami.gniibe.org> Simon Josefsson wrote: > Does this apply to the FST-01, FST-01G, or FST-01SZ? Does it depend on > how Gnuk was installed on the device? How would I protect them? For FST-01, FST-01G and FST-01SZ, when it is distributed with Gnuk by me, this does not apply. I distribute Gnuk Token with protection, always. Yes, it depends on how the firmware is installed on a device. The MCU has a configuration: the internal flash ROM can be protected against JTAG/SWD access. When the protection is not enabled, the internal flash ROM can be accessed by JTAG/SWD debugger. When it is an end user who does install Gnuk on FST-01/G/SZ through USB firmware upgrade, by neug/tool/neug_upgrade.py (for the one of NeuG installed device) or by gnuk/tool/upgrade_by_passwd.py (for the one of Gnuk installed device), it does the protection in its procedure, just after the flash ROM upgrade. For enabling protection after flash ROM installation by JTAG/SWD debugger, please have a look at the README, "How to protect flash ROM" section: https://git.gniibe.org/gitweb/?p=gnuk/gnuk.git;a=blob;f=README * * * For FST-01 as a NeuG standalone device, it was distributed with protection. For FST-01G as a NeuG standalone device, there were two cases: distributed with no protection or distributed with protection. For FST-01SZ as a NeuG standalone device, it is distributed with no protection. I distribute FST-01G/SZ as a NeuG standalone device, with no protection, because of reasons: (1) There are no private data on the device. (2) I (or an end user) may want to examine the content of flash ROM (the first 4KiB of ROM cannot be changed by the flash ROM upgrade, once protection done, no way to examine). (3) The protection will be enabled when another firmware will be installed. In the past, for FST-01's factory installation with Gnuk 1.0.1 (in 2012), I was careless about the fact of (2). In fact, the factory installation process of FST-01 was not that good and strict; I just prepared a tool set: ST-Link/V2 and USB-memory which included gnuk/tool/stlinkv2.py and Python USB (it was for Windows machine in a factory), and sent it to the factory. So, there were possibility where something bad was installed in the first 4KiB on FST-01, and it was kept unexamined. For FST-01 users, if this matters, it is recommended to install Gnuk by JTAG/SWD debugger to update the first 4KiB. When I asked the manufacturing of FST-01G in 2017, I defined more strict procedure: FST-01G Test Plan: https://www.gniibe.org/memo/development/fst-01/fst-01g-testplan.html In the procedure, I ask no protection, because of (2). When I asked the manufacturing of FST-01SZ for 2019 (in 2018), I defined this procedure: FST-01SZ Test Plan: https://www.gniibe.org/memo/development/fst-01/fst-01sz-testplan.html It's the same in the procedure, I ask no protection. And I have an explanation: https://www.gniibe.org/memo/development/fst-01/fst-01sz-testplan.html#locking-flash-access-by-swd When I did firmware upgrade of FST-01G to newer NeuG, I enabled the protection. That's why there were FST-01G with protection (while it is no protection at the factory). Well, to respect an end user's computing freedom, it would be better for a NeuG standalone device to have no protection when shipped. -- From nick at kousu.ca Wed May 29 22:40:07 2019 From: nick at kousu.ca (Nick) Date: Wed, 29 May 2019 20:40:07 +0000 Subject: [PATCH] Move bounds check inside ECC scalar multiply. Message-ID: The project's README says that contributions are welcome, but it's not that obvious to me how. With that said, I hope this is acceptable: I've submitted a merge request to your mirror. It makes `compute_kG` and `compute_kP` safer and more consistent to use. https://salsa.debian.org/gnuk-team/gnuk/gnuk/merge_requests/3 I welcome feedback to help improve this patch to a point where it would be acceptable for inclusion in your great fully free software project. As I said on the MR, I assign my copyright to the FSIJ, assuming it gets accepted. It's also included below --- src/ecc.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/ecc.c b/src/ecc.c index 2d637e9..4437e3e 100644 --- a/src/ecc.c +++ b/src/ecc.c @@ -119,6 +119,12 @@ FUNC(compute_kG) (ac *X, const bn256 *K) jpc Q[1], tmp[1], *dst; int i; int vk; + + if (bn256_is_zero(K)) /* < 1, it's too small. */ + return -1; + if (bn256_sub(K_dash, K, N) == 0) /* >= N, it's too big. */ + return -1; + uint32_t k_is_even = bn256_is_even (K); bn256_sub_uint (K_dash, K, k_is_even); @@ -241,7 +247,6 @@ FUNC(compute_kP) (ac *X, const bn256 *K, const ac *P) uint8_t index[86]; /* Lower 2-bit for index absolute value, msb is for sign (encoded as: 0 means 1, 1 means -1). */ bn256 K_dash[1]; - uint32_t k_is_even = bn256_is_even (K); jpc Q[1], tmp[1], *dst; int i; int vk; @@ -251,9 +256,13 @@ FUNC(compute_kP) (ac *X, const bn256 *K, const ac *P) if (point_is_on_the_curve (P) < 0) return -1; - if (bn256_sub (K_dash, K, N) == 0) /* >= N, it's too big. */ + if (bn256_is_zero(K)) /* < 1, it's too small. */ + return -1; + if (bn256_sub(K_dash, K, N) == 0) /* >= N, it's too big. */ return -1; + uint32_t k_is_even = bn256_is_even (K); + bn256_sub_uint (K_dash, K, k_is_even); /* It keeps the condition: 1 <= K' <= N - 2, and K' is odd. */ @@ -337,12 +346,9 @@ FUNC(ecdsa) (bn256 *r, bn256 *s, const bn256 *z, const bn256 *d) do { bn256_random (k); - if (bn256_add_uint (k, k, 1)) - continue; - if (bn256_sub (tmp_k, k, N) == 0) /* >= N, it's too big. */ + if(FUNC(compute_kG) (KG, k) < 0) continue; /* 1 <= k <= N - 1 */ - FUNC(compute_kG) (KG, k); borrow = bn256_sub (r, KG->x, N); if (borrow) memcpy (r, KG->x, sizeof (bn256)); @@ -372,8 +378,8 @@ FUNC(ecdsa) (bn256 *r, bn256 *s, const bn256 *z, const bn256 *d) /** * @brief Check if a secret d0 is valid or not * - * @param D0 scalar D0: secret - * @param D1 scalar D1: secret candidate N-D0 + * @param D0 scalar D0: secret candidate + * @param D1 scalar D1: secret candidate projected to N-D0 (output) * * Return 0 on error. * Return -1 when D1 should be used as the secret @@ -384,12 +390,12 @@ FUNC(check_secret) (const bn256 *d0, bn256 *d1) { ac Q0[1], Q1[1]; - if (bn256_is_zero (d0) || bn256_sub (d1, N, d0) != 0) - /* == 0 or >= N, it's not valid. */ + if(FUNC(compute_kG) (Q0, d0) < 0) + return 0; + bn256_sub (d1, N, d0); // carry is not checked here; + // the bounds check in compute_kG should hace caught the carry case + if(FUNC(compute_kG) (Q1, d1) < 0) return 0; - - FUNC(compute_kG) (Q0, d0); - FUNC(compute_kG) (Q1, d1); /* * Jivsov compliant key check -- 2.20.1 (Apple Git-117) From nick at kousu.ca Thu May 30 19:40:26 2019 From: nick at kousu.ca (Nick) Date: Thu, 30 May 2019 17:40:26 +0000 Subject: ecc.c: representing the point at infinity in affine coordinates Message-ID: <61c618f9600779652ed75459eb40d5c6@kousu.ca> In elliptic curves, the group operation needs an extra off-the-page point as the group identity, known conventionally as "infinity" or "the point at infinity" [0]. This point is, formally, unrepresentable as a pair (x,y) because it has no coordinates. But you need to have some way to deal with and check for this value. It is a legitimate -- and important -- part of EC arithmetic. Some standards, IEEE P1363, ANSI X9.62, and also secg [3] by choosing the single byte '\x00' to be infinity -- when serialized at least [5]. pycoin's ecc implementation similarly defines infinity at runtime as (None, None) [1] and then checks for it and handles it with special cases during addition [2]. I want to propose adopting the same idea into GnuK. Currently, `struct jpc` can handle points at infinity (and the arithmetic in jpc.c checks for ->z == 0 and behaves appropriately) but `struct ac` cannot. Instead, infinity is represent as an error code, e.g. `jpc_to_ac` says "Return -1 on error (infinite)" [4]. But this isn't really an error, it's just a representation in a side-channel. It would simplify much if this case was represented directly in the struct itself, since that could be passed around directly, and it wouldnt't get conflated with other kinds of errors. ac = {x: 0, y: 0} is unused in GnuK. It *must* be unused, since for an elliptic curve y^2 = x^3 + ax + b, if x = y = 0, then b = 0, but no supported elliptic curve has b = 0. This value could be repurposed as the point at infinity, and then the arithmetic would not need to have any error returns. Another representation would be to add a `bool infinite` flag to `struct ac`. The key thing is that I want to be able to return `ac`s the same way I can return `jpc`s and assume everything will check out. What do you all think about this? I wanted to run it by the experts here before I spent time editing a lot of parts of GnuK. [0]: https://en.wikipedia.org/wiki/Elliptic_curve#The_group_law [1]: https://github.com/richardkiss/pycoin/blob/facf208aafbe07d4d51d25b250a6f468c6c4198c/pycoin/ecdsa/Curve.py#L46 [2]: https://github.com/richardkiss/pycoin/blob/facf208aafbe07d4d51d25b250a6f468c6c4198c/pycoin/ecdsa/Curve.py#L74-L101 [3]: http://www.secg.org/sec1-v2.pdf#subsubsection.2.3.3 [4]: https://salsa.debian.org/gnuk-team/gnuk/gnuk/blob/177ef67edfa2306c2a369a037362385c354083e1/src/jpc.c#L188-L189 [5]: https://crypto.stackexchange.com/questions/6156/how-is-the-x-coordinate-of-a-point-at-infinity-encoded-in-a-secp256k1-signatur From gniibe at fsij.org Fri May 31 03:19:17 2019 From: gniibe at fsij.org (NIIBE Yutaka) Date: Fri, 31 May 2019 10:19:17 +0900 Subject: ecc.c: representing the point at infinity in affine coordinates In-Reply-To: <61c618f9600779652ed75459eb40d5c6@kousu.ca> References: <61c618f9600779652ed75459eb40d5c6@kousu.ca> Message-ID: <87sgsvfmju.fsf@iwagami.gniibe.org> Hello, "Nick" wrote: > In elliptic curves, the group operation needs an extra off-the-page > point as the group identity, known conventionally as "infinity" or > "the point at infinity" [0]. This point is, formally, unrepresentable > as a pair (x,y) because it has no coordinates. [...] I wonder if it's worth a try, in the codebase of Gnuk. I'm afraid not. Because users of Gnuk don't use classic ECC key, except a (very) minor use case of secp256k1. Another reason of my reluctance is that the special case of the point at infinity in classic ECC is considered a weakpoint which invites side-channel attacks to implementations. It would be hard to review such changes if it's large. On the other hand, with no support of the point at infinity, size of code to audit for this special case might be smaller. Well, let me explain the ECC situation in Gnuk. (This is a kind of duplicate, (IIRC, I wrote about it once somewhere), but perhaps, not here.) I implemented the ECC routines for the curve of NIST P-256 in 2013 and 2014, because it's faster and key size is smaller than RSA (I thought it were useful). It is my own implementation selecting among possible algorithms, so that I wouldn't be suffered from patent issues. But, then, around 2014, it was concluded that NIST P-256 is questionable to use, and it can not be recommended. In 2014, I extended the routines to support the curve of secp256k1. The intention was that Gnuk Token could be used for Bitcoin transactions (by developing a tool for that). And I proposed a way to publish a public key in OpenPGP format, so that people can make sure a Bitcoin address belongs to a person. At that time, I assumed a user (well, most of users) were in control of his private key when making Bitcoin transactions. Well, my assumption was simply wrong. It's not, for many of "Bitcoin users". And it seems that mostly nobody needs a representation in OpenPGP format binding Bitcoin public key to email address. And then, after Mt. Gox incident which happened in Japan, it made me difficult to keep working for anythong around Bitcoin support. Thus, I never wrote a tool issuing Bitcoin transaction with Gnuk Token. I know that my implementation is sub-optimal for secp256k1, but I intentionally did not introduce new algorithm for the curve, because of possible patent concern at that time. So, for implementation of the curve of secp256k1, you can find the Bitcoin one more useful, because it's faster for the particular curve. I think that the algorithm can be applied to Brainpool curves, too. -- From nick at kousu.ca Fri May 31 19:34:12 2019 From: nick at kousu.ca (Nick) Date: Fri, 31 May 2019 17:34:12 +0000 Subject: ecc.c: representing the point at infinity in affine coordinates In-Reply-To: <87sgsvfmju.fsf@iwagami.gniibe.org> References: <87sgsvfmju.fsf@iwagami.gniibe.org> <61c618f9600779652ed75459eb40d5c6@kousu.ca> Message-ID: May 30, 2019 10:19 PM, "NIIBE Yutaka" wrote: > Hello, > > "Nick" wrote: > >> In elliptic curves, the group operation needs an extra off-the-page >> point as the group identity, known conventionally as "infinity" or >> "the point at infinity" [0]. This point is, formally, unrepresentable >> as a pair (x,y) because it has no coordinates. > > [...] > > I wonder if it's worth a try, in the codebase of Gnuk. I'm afraid not. > Because users of Gnuk don't use classic ECC key, except a (very) minor > use case of secp256k1. Another reason of my reluctance is that the > special case of the point at infinity in classic ECC is considered a > weakpoint which invites side-channel attacks to implementations. It > would be hard to review such changes if it's large. On the other hand, > with no support of the point at infinity, size of code to audit for this > special case might be smaller. I don't envision the change being super invasive. I think I can just static const struct ac INFINITY = {0, 0}; add a ac_is_null() function that checks for this value, and then everywhere the arithmetic currently interprets this point, use/check for this value. For example - if (bn256_is_zero (A->z)) - return -1; + if (bn256_is_zero (A->z)) { + *X = INFINITY; + return 0; + } or - if (FUNC(jpc_to_ac) (P3, Q1) < 0) /* Never occurs, except coding errors. */ - return -1; + FUNC(jpc_to_ac) (P3, Q1); + if(FUNC(ac_is_null)(P3)) /* Never occurs, except coding errors. */ + return -1; We could also set INFINITY = {-1, 1} or {3, 4} or any other value that's unused. It could be defined per-curve, even. > Well, let me explain the ECC situation in Gnuk. (This is a kind of > duplicate, (IIRC, I wrote about it once somewhere), but perhaps, not > here.) > > I implemented the ECC routines for the curve of NIST P-256 in 2013 and > 2014, because it's faster and key size is smaller than RSA (I thought it > were useful). It is my own implementation selecting among possible > algorithms, so that I wouldn't be suffered from patent issues. > > But, then, around 2014, it was concluded that NIST P-256 is questionable > to use, and it can not be recommended. > > In 2014, I extended the routines to support the curve of secp256k1. > > The intention was that Gnuk Token could be used for Bitcoin transactions > (by developing a tool for that). And I proposed a way to publish a > public key in OpenPGP format, so that people can make sure a Bitcoin > address belongs to a person. > > At that time, I assumed a user (well, most of users) were in control of > his private key when making Bitcoin transactions. Well, my assumption > was simply wrong. It's not, for many of "Bitcoin users". And it seems > that mostly nobody needs a representation in OpenPGP format binding > Bitcoin public key to email address. > > And then, after Mt. Gox incident which happened in Japan, it made me > difficult to keep working for anythong around Bitcoin support. Thus, I > never wrote a tool issuing Bitcoin transaction with Gnuk Token. I see. That must have been discouraging. Thank you for the history lesson. Having the context and seeing the lineage of things is really helpful.