### Re: Review of draft-ecc-09

Andrey Jivsov <openpgp@brainhub.org> Thu, 23 February 2012 00:53 UTC

Received: from hoffman.proper.com (localhost [127.0.0.1]) by
hoffman.proper.com (8.14.5/8.14.3) with ESMTP id q1N0rKNE091299
(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO);
Wed, 22 Feb 2012 17:53:20 -0700 (MST) (envelope-from
owner-ietf-openpgp@mail.imc.org)

Received: (from majordom@localhost) by hoffman.proper.com
(8.14.5/8.13.5/Submit) id q1N0rKas091298;
Wed, 22 Feb 2012 17:53:20 -0700 (MST) (envelope-from
owner-ietf-openpgp@mail.imc.org)

X-Authentication-Warning: hoffman.proper.com: majordom set sender to
owner-ietf-openpgp@mail.imc.org using -f

Received: from qmta03.emeryville.ca.mail.comcast.net
(qmta03.emeryville.ca.mail.comcast.net [76.96.30.32]) by hoffman.proper.com
(8.14.5/8.14.3) with ESMTP id q1N0rJIr091293 for <ietf-openpgp@imc.org>;
Wed, 22 Feb 2012 17:53:20 -0700 (MST) (envelope-from openpgp@brainhub.org)

Received: from omta04.emeryville.ca.mail.comcast.net ([76.96.30.35]) by
qmta03.emeryville.ca.mail.comcast.net with comcast id dCbH1i0020lTkoCA3CtKcG;
Thu, 23 Feb 2012 00:53:19 +0000

Received: from [127.0.0.1] ([98.234.252.65]) by
omta04.emeryville.ca.mail.comcast.net with comcast id dCtJ1i00M1RRS8a8QCtJdi;
Thu, 23 Feb 2012 00:53:19 +0000

Message-ID: <4F458E56.4030802@brainhub.org>

Date: Wed, 22 Feb 2012 16:54:46 -0800

From: Andrey Jivsov <openpgp@brainhub.org>

User-Agent: Mozilla/5.0 (X11; Linux x86_64;
rv:10.0.1) Gecko/20120209 Thunderbird/10.0.1

MIME-Version: 1.0

To: Marko Kreen <markokr@gmail.com>

CC: ietf-openpgp@imc.org

Subject: Re: Review of draft-ecc-09

References: <20120218215115.GA18978@gmail.com> <4F4346B7.1040804@brainhub.org>
<20120221094901.GA27705@gmail.com>

In-Reply-To: <20120221094901.GA27705@gmail.com>

Content-Type: text/plain; charset=ISO-8859-1; format=flowed

Content-Transfer-Encoding: 7bit

Sender: owner-ietf-openpgp@mail.imc.org

Precedence: bulk

List-Archive: <http://www.imc.org/ietf-openpgp/mail-archive/>

List-Unsubscribe: <mailto:ietf-openpgp-request@imc.org?body=unsubscribe>

List-ID: <ietf-openpgp.imc.org>

Hello Marco: On 02/21/2012 01:49 AM, Marko Kreen wrote: > On Mon, Feb 20, 2012 at 11:24:39PM -0800, Andrey Jivsov wrote: >> On 02/18/2012 01:51 PM, Marko Kreen wrote: >>> [ I updated the review with diff from -09. Thanks for taking >>> my comments on the ref section into account. ] >> Sorry, I was busy in recent days and this is the first time I take >> close look at your feedback. The credit for -09 should go to Sean >> Turner, IETF Security Area director. > > Heh. I noticed few old references there, then the new draft > fixed those without me sending anything. > > Note - the links in text are not updated (see [nits] on draft page). > >>>> The point is encoded in MPI format. The content of the MPI is the >>>> following: >>>> >>>> B = B0 || x || y >>>> >>>> where x and y are coordinates of the point P = (x, y), each encoded >>>> in big endian format and zero-padded to the underlying field size. >>> *Then*, they are also padded to byte boundary. As this is not mentioned >>> anywhere, it caused me some confusion, because I assumed they already >>> are on byte boundary, perhaps even power-of-two. >>> >>> As it only matters to P-521 keys, the bad assumtions work fine on >>> P-256 and P-384 keys. (Basically I assumed P-521 uses 512-bit values...) >> >> Note, that what you are suggesting would not work in practice, if I >> understand your initial confusion correctly. Note that both x and y >> are taken mod a 521 bit prime. They can be exactly 521 bits, but in >> 50% of cases, 520 bits. Let's say that either x or y is 521 and >> another one is 520 bits. How would we know which one of x and y is >> the longest one? > > The text already states "zero-padded to the underlying field". > So we already are talking about bits in field, not bits > in actual bignum. > > The missing '*then*' part is about rounding field bits. > >> The algorithm is the following: given the MPI with the point, >> * get its size in full bytes ( len=(MPI_bits+7)/8 ) >> * len = len-1 ( to remove the B0 byte ) >> * len = len/2 -- the 'len' is the size of x and y in bytes. > > I think it's better to show how to calculate proper size > from field size, not from MPI size. Because MPI is "untrusted", > we need to validate it. > > Maybe just add: > > where x and y are coordinates of the point P = (x, y), each encoded > in big endian format and zero-padded to the underlying field size, > then zero-padded to multiple of 8 if the field size is not multiple of 8. > Yes, this makes it better. Here is modified text: "The point is encoded in MPI format. The content of the MPI is the following: B = B0 || x || y where x and y are coordinates of the point P = (x, y), each encoded in big endian format and zero-padded to the nearest 8-byte boundary that is higher or equal to the underlying field size. For example, for the 521 bit underlying field each x and y always occupy 66 bytes." ... and adjust the formula bellow in the spec and change the example to use P-521 to get 1059 total bit size recorded in the MPI header. >>> Missing detail: In addition to size check, what other validation must >>> be done when parsing a point? This applies to when reading a public key, >>> but especially when reading incoming ECDH/ECDSA message. I suggest >>> adding: "You must check that the point is on curve." here. >> >> I will take it as a suggestion and think how to integrate it, given >> that this is a general check for ECC and is not specific to OpenPGP. >> This valid concern may be satisfied through sources in References >> section. > > It's security detail, and it's simple to mention. > > The References are rather verbose, so it's easy to miss > the important details. > >>>> 8. EC DH Algorithm (ECDH) >>>> The key wrapping method is based on [RFC3394]. KDF produces the >>>> AES key that is used as KEK as specified in [RFC3394]. Refer to >>>> section 13 for the details regarding the choice of the KEK >>>> algorithm, which MUST be one of three AES algorithms. >>> This is only place which says that KEK *MUST* be AES-only. (Ignoring 12.2) >>> This is in conflict with section 12.1 and 13, where non-AES is not >>> disallowed. I'm not disagreeing with it, just I think it would be good >>> to clarify why. >>> >>> It might be good idea to disallow cipher_ids< AES128, but why disallow >>> Camellia and Twofish? I could imagine that because the algorithm >>> is not per-message but comes from key is the reason - you may not >>> know at key generation time all the people who want to send you messages >>> and what features their software has. But I think it would be >>> good to put the reason in the doc. >>> >>> In any case, 12.1 and 13 should be synced with the requirement. >> >> I also see the need for clarity here. >> >> In reference to compatibility, if the code understands ECC, the >> document assumes that it must supports AES. This is something >> OpenPGP RFC 4880 cannot generally rely upon. One of main criteria of >> this document is simplicity through limited choices, as I recall, >> something that Ian G advocated. It's much easier to write "use AES" >> than to define "strong enough" cipher. > > cipher_num> 7? > >> Suite B and other government >> standards require AES, so most application will implement it to >> comply, leaving us with the question why bother at all about the >> non-AES case? >> >> I am leaning toward fixing KEK at AES. There is no backward >> compatibility issue here. So, the action item for me is to make this >> choice clear. > > Fine by me. > >>>> For convenience, the synopsis of the encoding method is given >>>> below, however, this section, [NIST SP800-56A], and [RFC3394] are >>>> the normative sources of the definition. >>>> >>>> Obtain authenticated recipient public key R >>>> Generate ephemeral key pair {v, V=vG} >>>> Compute shared point S = vR; >>>> m = symm_alg_ID || session key || checksum || pkcs5_padding; >>>> curve_OID_len = (byte)len(curve_OID); >>>> Param = curve_OID_len || curve_OID || public_key_alg_ID || 03 || >>>> 01 || KDF_hash_ID || AES_alg_ID for AESKeyWrap || >>>> "Anonymous Sender " || recipient_fingerprint; >>>> Z_len = key size for AES_alg_ID to be used with AESKeyWrap >>>> Compute Z = KDF( S, Z_len, Param ); >>>> Compute C = AESKeyWrap( Z, m ) as per [RFC3394] >>>> VB = convert point V to octet string >>>> Output (MPI(VB) || len(C) || C). >>>> >>>> The decryption is the inverse of the method given. Note that the >>>> recipient obtains the shared secret by calculating >>>> >>>> S = rV = rvG, where (r,R) is the recipient's key pair. >>>> >>>> Consistent with section 5.13 Sym. Encrypted Integrity Protected >>>> Data Packet (Tag 18) of [RFC4880], the MDC SHOULD be used anytime >>>> symmetric key is protected by ECDH. >>> Missing detail: How to generate v? What requirements it has? >>> I suggest expanding the second step with: >>> >>> Generate ephemeral key pair {v, V} where V=vG and v is random number >>> in range 0< v< n (n - curve modulus) >> This detail is also related to a question of external reference, but >> I am glad you raised this question. FIPS 186-3 defines two methods >> in B.4 on p.61. The idea is this: >> B.4.1: if you do "v = v' mod order", the input v' must be 64 bits >> longer than "order". >> B.4.2: or you can repeatedly getting random bits until "v'< order" >> (probably too wasteful for the entropy) > > I think the "How" can be left to references. I just would like > to see the requirement "0< v< n" mentioned here. > > RFC6090 Appendix A seems even better reference for this. > It seems to reference only method B.4.2. I find that method B.4.1 is more practical. >>> Final note: the section 8 was quite successful at describing ECDH, >>> how hard would it be to have same level of description of ECDSA here? >>> At least I would like to see packet format here, even if the >>> algorithm is not described. >> >> Marko, did you realize that it happens that the signature format for >> ECDSA is identical to DSA? > > Well, FIPS 186-3 tells that actual ECDSA is described in ANS X9.62.. > >> The (r,s) signature pair consists of >> (true) MPIs in both cases. The ECDSA key is defined in section 9. >> Overall, ECDSA for OpenPGP is much simpler because it has no >> complexities like key wrapping. With this in mind, what would you >> like to see added to properly implement ECDSA. > > At minimum, it should mention that > > Algorithm-Specific Fields for ECDSA signatures are: > - MPI of ECDSA value r. > - MPI of ECDSA value s. > > then the spec makes clear the mapping between packet layout > and algorithm. > > I would like to see short algorithm description also here, > with symbols consistent with rest of the document. > > But it's proably OK having good reference in the form "OpenPGP variant > of ECDSA is described here: [REF]". And if the REF describes 4 > different EC signature variants, then point directly to section. > > Eg: "How to pad/shorten H(m) for use in ECDSA" is another > step that needs clear "in OpenPGP we do it like this" > description. (shorten: trunc-left/trunc-right/mod. And how short?) > Thank you for your comments.

- Re: Review of draft-ecc-09 Andrey Jivsov
- Re: Review of draft-ecc-09 Marko Kreen
- Re: Review of draft-ecc-09 Andrey Jivsov
- Re: Review of draft-ecc-09 Marko Kreen
- Review of draft-ecc-09 Marko Kreen
- Re: Review of draft-ecc-10 Andrey Jivsov
- Review of draft-ecc-10 Marko Kreen