.\" This file is in the public domain. .Dd March 31, 2005 .Dt LIBSHA 3 .Os NetBSD 1.4T .Sh NAME .Nm sha_init , .Nm sha_process_bytes , .Nm sha_result , .Nm sha_clone , .Nm sha_state , .Nm sha_set_state , .Nm sha_drop , .Nm sha1_init , .Nm sha1_process_bytes , .Nm sha1_result , .Nm sha1_clone , .Nm sha1_state , .Nm sha1_set_state , .Nm sha1_drop , .Nm sha256_init , .Nm sha256_process_bytes , .Nm sha256_result , .Nm sha256_clone , .Nm sha256_state , .Nm sha256_set_state , .Nm sha256_drop , .Nm sha384_init , .Nm sha384_process_bytes , .Nm sha384_result , .Nm sha384_clone , .Nm sha384_state , .Nm sha384_set_state , .Nm sha384_drop , .Nm sha512_init , .Nm sha512_process_bytes , .Nm sha512_result , .Nm sha512_clone , .Nm sha512_state , .Nm sha512_set_state , .Nm sha512_drop , .Nm shaX_init , .Nm shaX_number , .Nm shaX_hashsize , .Nm shaX_max_hashsize , .Nm shaX_process_bytes , .Nm shaX_result , .Nm shaX_clone , .Nm shaX_state , .Nm shaX_set_state , .Nm shaX_drop .Nd SHA hashing routines .Sh SYNOPSIS .Fd #include .br .Nm cc .Op Ar arguments .Fl lsha .br .Ft void * .Fn sha_init "void" .Ft void .Fn sha_process_bytes "void *handle" "const void *buf" "unsigned int len" .Ft void .Fn sha_result "void *handle" "unsigned char *resbuf" .Ft void * .Fn sha_clone "const void *handle" .Ft int .Fn sha_state "const void *handle" "void *buf" "int bufsize" .Ft int .Fn sha_set_state "void *handle" "const void *buf" "int bufsize" .Ft void .Fn sha_drop "void *handle" .br .Ft void * .Fn sha1_init "void" .Ft void .Fn sha1_process_bytes "void *handle" "const void *buf" "unsigned int len" .Ft void .Fn sha1_result "void *handle" "unsigned char *resbuf" .Ft void * .Fn sha1_clone "const void *handle" .Ft int .Fn sha1_state "const void *handle" "void *buf" "int bufsize" .Ft int .Fn sha1_set_state "void *handle" "const void *buf" "int bufsize" .Ft void .Fn sha1_drop "void *handle" .br .Ft void * .Fn sha256_init "void" .Ft void .Fn sha256_process_bytes "void *handle" "const void *buf" "unsigned int len" .Ft void .Fn sha256_result "void *handle" "unsigned char *resbuf" .Ft void * .Fn sha256_clone "const void *handle" .Ft int .Fn sha256_state "const void *handle" "void *buf" "int bufsize" .Ft int .Fn sha256_set_state "void *handle" "const void *buf" "int bufsize" .Ft void .Fn sha256_drop "void *handle" .br .Ft void * .Fn sha384_init "void" .Ft void .Fn sha384_process_bytes "void *handle" "const void *buf" "unsigned int len" .Ft void .Fn sha384_result "void *handle" "unsigned char *resbuf" .Ft void * .Fn sha384_clone "const void *handle" .Ft int .Fn sha384_state "const void *handle" "void *buf" "int bufsize" .Ft int .Fn sha384_set_state "void *handle" "const void *buf" "int bufsize" .Ft void .Fn sha384_drop "void *handle" .br .Ft void * .Fn sha512_init "void" .Ft void .Fn sha512_process_bytes "void *handle" "const void *buf" "unsigned int len" .Ft void .Fn sha512_result "void *handle" "unsigned char *resbuf" .Ft void * .Fn sha512_clone "const void *handle" .Ft int .Fn sha512_state "const void *handle" "void *buf" "int bufsize" .Ft int .Fn sha512_set_state "void *handle" "const void *buf" "int bufsize" .Ft void .Fn sha512_drop "void *handle" .br .Ft void * .Fn shaX_init "int number" .Ft int .Fn shaX_number "const void *handle" .Ft int .Fn shaX_hashsize "const void *handle" .Ft int .Fn shaX_max_hashsize "void" .Ft int .Fn shaX_process_bytes "void *handle" "const void *buf" "unsigned int len" .Ft void .Fn shaX_result "void *handle" "unsigned char *resbuf" .Ft void * .Fn shaX_clone "const void *handle" .Ft int .Fn shaX_state "const void *handle" "void *buf" "int bufsize" .Ft int .Fn shaX_set_state "void *handle" "const void *buf" "int bufsize" .Ft void .Fn shaX_drop "void *handle" .Sh DESCRIPTION These functions perform SHA hashing: the original SHA, SHA-1, SHA-256, SHA-384, and SHA-512. These are as specified in USA Government Federal Information Processing Standards Publication 180, of May 11, 1993, and its successors 180-1 and 180-2. (Note that SHA and, to a lesser extent, SHA-1, are known to be insecure against certain classes of attacks; they should be used cautiously if at all.) .Pp Each algorithm has its own set of functions, with a prefix that matches the algorithm used: .Nm sha_ for SHA, .Nm sha1_ for SHA-1, .Nm sha256_ for SHA-256, .Nm sha384_ for SHA-384, and .Nm sha512_ for SHA-512. There is also a similar set of functions that work with any of the algorithms, with the particular algorithm chosen at init time; they use .Nm shaX_ as a prefix. Using the SHA functions as a paradigmmatic example (with the prefix replaced for any of the other algorithm-specific versions, and the hash size changed suitably for the .Nm _result function), there are: .Bl -tag -width indent .It Fn sha_init This must be the first call; it returns a .Sy handle , which is opaque to the caller and must be passed to the other functions. .Nm sha_init takes no arguments, always either creating and returning a new handle or returning a nil pointer if it couldn't allocate the required memory. Multiple handles may be active at once; each handle is an independent hash-in-progress. .It Fn sha_process_bytes This is the way one feeds data into a hash operation. It takes the handle of the hash, a pointer to a buffer holding the data to be hashed, and the number of bytes to be hashed. .It Fn sha_result This computes the 160-bit result, the hash of all bytes that have been fed into the hash operation whose handle is passed in. The result is written into the provided .Fa resbuf , which is assumed to be a 20-byte buffer. The handle is also freed and must never be used again. .It Fn sha_clone This duplicates a hash-in-progress, returning a distinct handle equivalent to the one passed as an argument (or a nil pointer if memory allocation failed) \&- that is, they will function equivalently in further calls. This is equivalent to calling .Nm sha_init again and then .Nm sha_process_bytes on the same sequence of bytes that was done on the first handle. However, it should be emphasized that after the .Nm sha_clone call, the two handles are as completely independent as any two distinct handles; they are in no way tied together simply because one was obtained as a clone of the other. .It Fn sha_state This returns the internal state of a hash-in-progress, encoded as a string of bytes. .Fa buf must be a pointer to a buffer to hold the state; .Fa bufsize must be the size of the buffer. The return value is the number of bytes .Nm sha_state would like to place in .Fa buf . If this is no greater than .Fa bufsize , then the returned state is complete and may be saved for later passing to .Nm sha_set_state ; otherwise, .Fa buf Ns ' Ns s contents are indeterminate. If .Fa bufsize is zero, .Fa buf is ignored and does not have to be a valid pointer; however, the return value is still accurate. The amount of space required may vary, but the library promises that it will not change between two successive calls to .Nm sha_state on the same handle if no intervening .Nm sha_process_bytes calls are made on that handle. .It Fn sha_set_state This takes a pointer to an existing .F handle and buffer parameters like .Nm sha_state Ns ' Ns s , loading the state into the hash-in-progress, replacing the state already there. There are some (weak) consistency checks; if the state shows evidence of having been corrupted, or if it's from an unrecognized version of the library, the call fails, and the return value will be one of these nonzero manifest constants: .Bl -tag -width indent .It Dv SHA_BADVERS The library version number is wrong. .It Dv SHA_CORRUPT The state has been corrupted. In this case, the .Fa state block may have been modified; the remarks below about the effects of undetected state corruption apply here too. .El .\" There really ought to be a better way than this of getting a blank line .\" after a list! I really don't understand why the default is a blank line .\" before the list and none after. .Pp Otherwise (on success), the return value will be zero. It may be possible for state corruption to go undetected. If this happens, the library promises that it will not crash as a result, but if a hash value is eventually computed based on the loaded state, it may be garbage (it may not bear any relation to the result of applying the algorithm to any sequence of bytes). If the .Fa bufsize value is smaller than the return value from the .Nm sha_state call that produced the data, this constitutes corruption, but it may be larger without harm (any extra bytes will be ignored). .It Fn sha_drop This discards a hash-in-progress without computing a final hash. It is semantically equivalent to calling .Nm sha_result and ignoring the result buffer, but somewhat more efficient. .El .Pp The .Nm shaX_ set of functions is similar, except that the calling convention for the init function is different, the rest of the functions can operate on handles for any of the hash algorithms, and there are a few functions which have no algorithm-specific counterparts. When using these generic versions, the algorithm used is the one for which the handle was created. Calls may be freely intermixed between the generic functions and the algorithm-specific functions that go with the handle's algorithm, but using a handle created for one algorithm with an algorithm-specific function for a different algorithm is considered a critical error and the library will call .Xr abort 3 . (If the call to .Xr abort 3 returns for any reason, the library will not crash, but will not perform any useful operation.) .Pp The algorithm-specific .Nm _set_state functions require that the handle be for the correct algorithm, like the rest of the functions, but if the state data is for a different algorithm, they return .Dv SHA_CORRUPT rather than calling .Xr abort 3 ) . However, .Nm shaX_set_state does not require that the existing handle's algorithm match the algorithm of the data block; it will change the handle's algorithm to match the data block's in case of a mismatch. .Pp Omitting the functions which are completely parallel to the algorithm-specific versions, the generic functions are: .Bl -tag -width indent .It Fn shaX_init This is just like the algorithm-specific init functions except that it takes an argument specifying which algorithm to use. This argument must be a number: 0 for SHA, 1 for SHA-1, 256 for SHA-256, 384 for SHA-384, and 512 for SHA-512. If an unrecognized argument is passed, a nil pointer is returned. .It Fn shaX_number This returns the algorithm number for a handle; algorithm numbers are as specified for the argument to .Nm shaX_init . .It Fn shaX_hashsize This returns the size in bytes (not bits) of a hash from the handle's algorithm. It does not affect the handle's state in any way. .It Fn shaX_max_hashsize This returns the maximum .Nm _hashsize value for any supported algorithm. It may be used to, for example, determine an allocation size for algorithm-independent hash buffers. .El .Pp State data blocks returned by .Nm _state functions and accepted by .Nm _set_state functions are portable between the same library version built for different machine architectures, but not necessarily between different versions of the library. .Sh ERRORS If an .Nm _init or .Nm _clone function cannot allocate enough memory for a new handle, or if .Nm shaX_init is passed an invalid argument, it returns a nil pointer. Algorithm mismatches between functions called and handles, as described above, will produce calls to .Xr abort 3 , as will calls to the generic functions when the passed-in data is detectably garbage. No other failure conditions are possible, assuming .Xr malloc 3 and .Xr free 3 conform to their interfaces correctly; the only possible failure modes are due to passing invalid pointers or corrupting the malloc arena such that .Xr malloc 3 or .Xr free 3 fails catastrophically. The library makes no attempt to detect such conditions; effects can range from none to incorrect hashes to core dumps to silent corruption of memory. .Sh BUGS No provision is made for hashing a number of bits that is not an exact number of bytes. .Pp Code blindly assumes 8-bit .Do char .Dc Ns s. .Sh AUTHOR der Mouse, .Aq mouse@rodents.montreal.qc.ca .