On March 23, 2004 01:22 pm, Rich Salz wrote: > >>>The bug is: when flen is not the RSA key size (e.g., 32 bytes), the > >>>function returns -1 and no encryption is done. > > > > What is the principle behind this design? > > RSA works on input that has the same number of bits as the RSA key > size. (An earlier message from you disagreed with this; you're wrong.) > > In other words, a 1024-bit RSA key works on 1024 bits of input and > returns 1024 bits of output. If your input is not the same size as the > key, you must use padding to make it so. If you do not use padding, > than the RSA algorithm cannot be executed.
Are we perhaps talking at cross-purposes? The RSA algorithm can indeed be executed against any numeric input smaller than the modulus. The difference here is that the RSA API in openssl operates on an endian-agnostic strings of bytes, whereas the RSA algorithm itself operates on multi-precision numbers smaller than the modulus. The mathematical requirements of RSA are a subset of the representation requirements of the API, which includes pre-processing and post-processing steps for numeric conversions and padding implementations (and checks). Like the other padding modes, RSA_NO_PADDING is handled by a pre-processor, RSA_padding_add_none(), which insists that input and output byte buffers have the same length, and the way this is invoked from the RSA implementation in rsa_eay.c equates the output buffer length (which is not supplied as a parameter in the API) with the number of bytes of the RSA modulus. This is the real problem. The limitation, in other words, is the API :-) I would actually agree that RSA_NO_PADDING is counter-intuitive, it really means RSA_ALREADY_PADDED. The problem is that RSA_[public|private]_[encrypt|decrypt], as well as RSA_sign and RSA_verify, only take a single length parameter. The function can not therefore know what length the output buffer is if it can't assume this to match the length of the input, and so it enforces the (draconian) rule that this input must be at least as large as the modulus. The reason? The output is always less than the modulus and so this is always "big enough". There is no compelling reason though that the input needs to be this big though. On the other side, the reason the input can not be larger than the modulus length is that if the numeric representation is larger than the modulus, the inverse operation won't match (though will be congruent). Of course "same length" can still mean "greater value" ... So putting the two together we force the lengths to match, which is purely a byte-representation and API problem. The real algorithmic check is buried further in the code, which requires that the numeric input (once converted from the byte string input) is smaller than 'n'. Sorry Rich, didn't mean to stir pointlessly. Your solution is right (from outside the API), zero-pad the input to be the same number of bytes as the RSA modulus. However, the explanation seemed wrong or at least misleading - the conceptual problem is not the algorithm, it's the API. Cheers, Geoff -- Geoff Thorpe [EMAIL PROTECTED] http://www.geoffthorpe.net/ ______________________________________________________________________ OpenSSL Project http://www.openssl.org Development Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]