crypt.tex
来自「文件驱动加密,功能强大,可产生加密分区,支持AES,MD2,MD4,MD5MD2」· TEX 代码 · 共 1,456 行 · 第 1/5 页
TEX
1,456 行
This will initialize the ``ocb'' context using cipher descriptor ``cipher''. It will use a ``key'' of length ``keylen''and the random ``nonce''. Note that ``nonce'' must be a random (public) string the same length as the block ciphersblock size (e.g. 16 for AES).This mode has no ``Associated Data'' like EAX mode does which means you cannot authenticate metadata along with the stream.To encrypt or decrypt data use the following.\begin{verbatim}int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct);int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt);\end{verbatim}This will encrypt (or decrypt for the latter) a fixed length of data from ``pt'' to ``ct'' (vice versa for the latter). They assume that ``pt'' and ``ct'' are the same size as the block cipher's block size. Note that you cannot call both functions given a single ``ocb'' state. For bi-directional communication you will have to initialize two ``ocb''states (with difference nonces). Also ``pt'' and ``ct'' may point to the same location in memory.When you are finished encrypting the message you call the following function to compute the tag.\begin{verbatim}int ocb_done_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tag, unsigned long *taglen);\end{verbatim}This will terminate an encrypt stream ``ocb''. If you have trailing bytes of plaintext that will not complete a block you can pass them here. This will also encrypt the ``ptlen'' bytes in ``pt'' and store them in ``ct''. It will alsostore upto ``taglen'' bytes of the tag into ``tag''.Note that ``ptlen'' must be less than or equal to the block size of block cipher chosen. Also note that if you have an input message equal to the length of the block size then you pass the data here (not to ocb\_encrypt()) only. To terminate a decrypt stream and compared the tag you call the following.\begin{verbatim}int ocb_done_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt, const unsigned char *tag, unsigned long taglen, int *res);\end{verbatim}Similarly to the previous function you can pass trailing message bytes into this function. This will compute the tag of the message (internally) and then compare it against the ``taglen'' bytes of ``tag'' provided. By default``res'' is set to zero. If all ``taglen'' bytes of ``tag'' can be verified then ``res'' is set to one (authenticatedmessage).To make life simpler the following two functions are provided for memory bound OCB.\begin{verbatim}int ocb_encrypt_authenticate_memory(int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *nonce, const unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tag, unsigned long *taglen);\end{verbatim}This will OCB encrypt the message ``pt'' of length ``ptlen'' and store the ciphertext in ``ct''. The length ``ptlen''can be any arbitrary length. \begin{verbatim}int ocb_decrypt_verify_memory(int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *nonce, const unsigned char *ct, unsigned long ctlen, unsigned char *pt, const unsigned char *tag, unsigned long taglen, int *res);\end{verbatim}Similarly this will OCB decrypt and compare the internally computed tag against the tag provided. ``res'' is set appropriately.\chapter{One-Way Cryptographic Hash Functions}\section{Core Functions}Like the ciphers there are hash core functions and a universal data type to hold the hash state called ``hash\_state''. To initialize hash XXX (where XXX is the name) call:\index{Hash Functions}\begin{verbatim}void XXX_init(hash_state *md);\end{verbatim}This simply sets up the hash to the default state governed by the specifications of the hash. To add data to the message being hashed call:\begin{verbatim}int XXX_process(hash_state *md, const unsigned char *in, unsigned long len);\end{verbatim}Essentially all hash messages are virtually infinitely\footnote{Most hashes are limited to $2^{64}$ bits or 2,305,843,009,213,693,952 bytes.} long message which are buffered. The data can be passed in any sized chunks as long as the order of the bytes are the same the message digest(hash output) will be the same. For example, this means that:\begin{verbatim}md5_process(&md, "hello ", 6);md5_process(&md, "world", 5);\end{verbatim}Will produce the same message digest as the single call:\index{Message Digest}\begin{verbatim}md5_process(&md, "hello world", 11);\end{verbatim}To finally get the message digest (the hash) call:\begin{verbatim}int XXX_done(hash_state *md, unsigned char *out);\end{verbatim}This function will finish up the hash and store the result in the ``out'' array. You must ensure that ``out'' is longenough for the hash in question. Often hashes are used to get keys for symmetric ciphers so the ``XXX\_done()'' functionswill wipe the ``md'' variable before returning automatically.To test a hash function call:\begin{verbatim}int XXX_test(void);\end{verbatim}This will return {\bf CRYPTO\_OK} if the hash matches the test vectors, otherwise it returns an error code. Anexample snippet that hashes a message with md5 is given below.\begin{small}\begin{verbatim}#include <mycrypt.h>int main(void){ hash_state md; unsigned char *in = "hello world", out[16]; /* setup the hash */ md5_init(&md); /* add the message */ md5_process(&md, in, strlen(in)); /* get the hash in out[0..15] */ md5_done(&md, out); return 0;}\end{verbatim}\end{small}\section{Hash Descriptors}\index{Hash Descriptors}Like the set of ciphers the set of hashes have descriptors too. They are stored in an array called ``hash\_descriptor'' andare defined by:\begin{verbatim}struct _hash_descriptor { char *name; unsigned long hashsize; /* digest output size in bytes */ unsigned long blocksize; /* the block size the hash uses */ void (*init) (hash_state *); int (*process)(hash_state *, const unsigned char *, unsigned long); int (*done) (hash_state *, unsigned char *); int (*test) (void);};\end{verbatim}Similarly ``name'' is the name of the hash function in ASCII (all lowercase). ``hashsize'' is the size of the digest outputin bytes. The remaining fields are pointers to the functions that do the respective tasks. There is a function tosearch the array as well called ``int find\_hash(char *name)''. It returns -1 if the hash is not found, otherwise theposition in the descriptor table of the hash.You can use the table to indirectly call a hash function that is chosen at runtime. For example:\begin{small}\begin{verbatim}#include <mycrypt.h>int main(void){ unsigned char buffer[100], hash[MAXBLOCKSIZE]; int idx, x; hash_state md; /* register hashes .... */ if (register_hash(&md5_desc) == -1) { printf("Error registering MD5.\n"); return -1; } /* register other hashes ... */ /* prompt for name and strip newline */ printf("Enter hash name: \n"); fgets(buffer, sizeof(buffer), stdin); buffer[strlen(buffer) - 1] = 0; /* get hash index */ idx = find_hash(buffer); if (idx == -1) { printf("Invalid hash name!\n"); return -1; } /* hash input until blank line */ hash_descriptor[idx].init(&md); while (fgets(buffer, sizeof(buffer), stdin) != NULL) hash_descriptor[idx].process(&md, buffer, strlen(buffer)); hash_descriptor[idx].done(&md, hash); /* dump to screen */ for (x = 0; x < hash_descriptor[idx].hashsize; x++) printf("%02x ", hash[x]); printf("\n"); return 0;}\end{verbatim}\end{small}Note the usage of ``MAXBLOCKSIZE''. In Libtomcrypt no symmetric block, key or hash digest is larger than MAXBLOCKSIZE inlength. This provides a simple size you can set your automatic arrays to that will not get overrun.There are three helper functions as well:\index{hash\_memory()} \index{hash\_file()}\begin{verbatim}int hash_memory(int hash, const unsigned char *data, unsigned long len, unsigned char *dst, unsigned long *outlen);int hash_file(int hash, const char *fname, unsigned char *dst, unsigned long *outlen);int hash_filehandle(int hash, FILE *in, unsigned char *dst, unsigned long *outlen);\end{verbatim}The ``hash'' parameter is the location in the descriptor table of the hash (\textit{e.g. the return of find\_hash()}). The ``*outlen'' variable is used to keep track of the output size. Youmust set it to the size of your output buffer before calling the functions. When they complete succesfully they storethe length of the message digest back in it. The functions are otherwise straightforward. The ``hash\_filehandle'' function assumes that ``in'' is an file handle opened in binary mode. It will hash to the end of file and not resetthe file position when finished.To perform the above hash with md5 the following code could be used:\begin{small}\begin{verbatim}#include <mycrypt.h>int main(void){ int idx, errno; unsigned long len; unsigned char out[MAXBLOCKSIZE]; /* register the hash */ if (register_hash(&md5_desc) == -1) { printf("Error registering MD5.\n"); return -1; } /* get the index of the hash */ idx = find_hash("md5"); /* call the hash */ len = sizeof(out); if ((errno = hash_memory(idx, "hello world", 11, out, &len)) != CRYPT_OK) { printf("Error hashing data: %s\n", error_to_string(errno)); return -1; } return 0;}\end{verbatim}\end{small}The following hashes are provided as of this release:\begin{center}\begin{tabular}{|c|c|c|} \hline Name & Descriptor Name & Size of Message Digest (bytes) \\ \hline WHIRLPOOL & whirlpool\_desc & 64 \\ \hline SHA-512 & sha512\_desc & 64 \\ \hline SHA-384 & sha384\_desc & 48 \\ \hline SHA-256 & sha256\_desc & 32 \\ \hline SHA-224 & sha224\_desc & 28 \\ \hline TIGER-192 & tiger\_desc & 24 \\ \hline SHA-1 & sha1\_desc & 20 \\ \hline RIPEMD-160 & rmd160\_desc & 20 \\ \hline RIPEMD-128 & rmd128\_desc & 16 \\ \hline MD5 & md5\_desc & 16 \\ \hline MD4 & md4\_desc & 16 \\ \hline MD2 & md2\_desc & 16 \\ \hline\end{tabular}\end{center}Similar to the cipher descriptor table you must register your hash algorithms before you can use them. These functionswork exactly like those of the cipher registration code. The functions are:\begin{verbatim}int register_hash(const struct _hash_descriptor *hash);int unregister_hash(const struct _hash_descriptor *hash);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?