On 15 Sep 2009 Wan-Teh Chang wrote:
On Tue, Sep 15, 2009 at 8:51 AM, Andreev Konstantin <[email protected]> wrote:At the moment NSS head supports 6 hash algorithm: md2,md5,sha{,-256,-384,-512}. However, their implementations in freebl backend have no consistent semantics for method *hash*_End( Context *, unsigned char *digest, unsigned int *digestLen, unsigned int maxDigestLen ) Look how various hashes handle (maxDigestLen < REAL_HASH_LENGTH) case: MD2_End,MD5_End: PORT_SetError(SEC_ERROR_INVALID_ARGS) then return. - there is no other indication to the caller about error occured - they do not care about clearing error if maxDigestLen is sufficient SHA1_End: application dies with post-mortem message. SHA{256,384,512}_End: return only maxDigestLen of digest - there is no error indication to the caller at all I should correctly add GOST hash algorithm to the NSS, but which semantics should I implement for GOST_End() ? I would propose to unify *hash*_End() semantics for (maxDigestLen < REAL_HASH_LENGTH) as follows: 1) return only maxDigestLen of digest 2) always set digestLen to the real hash length. 3) do *not* kill application (this is unfriendly), do not SetError(). The caller can always detect digest buffer shortage from the fact (digestLen > maxDigestLen), and caller now knows required buffer length from digestLen.Thank you for the bug report. The semantics of SHA{256,384,512}_End are the closest to what I would expect, based on my experience with other NSS crypto functions. I would expect that on return, *digestLen contains the number of bytes written. [... SKIP ...]
The function signature *hash*_End( , , unsigned *digestLen, unsigned maxDigestLen ) let assume that the original goal of this design - is to ensure dynamic configuration of the buffer length in two steps. This is like GNU libc 'snprintf()' or Win32 'GetTempPath()', etc. At 1st step you try to accomplish the action with buffer of arbitrary length (including zero), and, if the length is not sufficient, you get back the length of the buffer required. At 2nd step you accomplish the action. To support this scenario *hash*_End() should place required length to digestLen. Placing the number of bytes written into the digestLen is less useful, - we can only be sure digest is written completely if (digestLen < maxDigestLen). If (digestLen >= maxDigestLen) we do not know neither we have full digest, nor which length it is. To Robert Relyea: On 15 Sep 2009 you wrote about "Rus GOST 89":
... solution would be to add the new algorithm as a separately loaded PKCS #11 module [... SKIP ...] The one thing I still really need to make this work is a way to automatically add the new algorithm's configuration.
May the scenario above reduce the number of configuration parameters for dynamically added hash algorithms ? Best regards, -- Konstantin Andreev, software engineer. -- dev-tech-crypto mailing list [email protected] https://lists.mozilla.org/listinfo/dev-tech-crypto

