/** add header (metadata) to the stream @param eax The current EAX state @param header The header (meta-data) data you wish to add to the state @param length The length of the header data @return CRYPT_OK if successful */ int eax_addheader(eax_state *eax, const unsigned char *header, unsigned long length) { LTC_ARGCHK(eax != NULL); LTC_ARGCHK(header != NULL); return omac_process(&eax->headeromac, header, length); }
int eax_decryptx( const unsigned char ct[], unsigned char pt[], unsigned long length, eax_state eax[1] ) { int err; if( (err = omac_process( ct, length, eax->ctx_omac )) != EXIT_SUCCESS ) return err; return ctr_decrypt( ct, pt, length, eax->ctr ); }
/** OMAC multiple blocks of memory @param cipher The index of the desired cipher @param key The secret key @param keylen The length of the secret key (octets) @param out [out] The destination of the authentication tag @param outlen [in/out] The max size and resulting size of the authentication tag (octets) @param in The data to send through OMAC @param inlen The length of the data to send through OMAC (octets) @param ... tuples of (data,len) pairs to OMAC, terminated with a (NULL,x) (x=don't care) @return CRYPT_OK if successful */ int omac_memory_multi(int cipher, const unsigned char *key, unsigned long keylen, unsigned char *out, unsigned long *outlen, const unsigned char *in, unsigned long inlen, ...) { int err; omac_state *omac; va_list args; const unsigned char *curptr; unsigned long curlen; LTC_ARGCHK(key != NULL); LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* allocate ram for omac state */ omac = XMALLOC(sizeof(omac_state)); if (omac == NULL) { return CRYPT_MEM; } /* omac process the message */ if ((err = omac_init(omac, cipher, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } va_start(args, inlen); curptr = in; curlen = inlen; for (;;) { /* process buf */ if ((err = omac_process(omac, curptr, curlen)) != CRYPT_OK) { goto LBL_ERR; } /* step to next */ curptr = va_arg(args, const unsigned char*); if (curptr == NULL) { break; } curlen = va_arg(args, unsigned long); } if ((err = omac_done(omac, out, outlen)) != CRYPT_OK) { goto LBL_ERR; } LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(omac, sizeof(omac_state)); #endif XFREE(omac); va_end(args); return err; }
/** LTC_OMAC a block of memory @param cipher The index of the desired cipher @param key The secret key @param keylen The length of the secret key (octets) @param in The data to send through LTC_OMAC @param inlen The length of the data to send through LTC_OMAC (octets) @param out [out] The destination of the authentication tag @param outlen [in/out] The max size and resulting size of the authentication tag (octets) @return CRYPT_OK if successful */ int omac_memory(int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { int err; omac_state *omac; LTC_ARGCHK(key != NULL); LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* is the cipher valid? */ if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { return err; } /* Use accelerator if found */ if (cipher_descriptor[cipher].omac_memory != NULL) { return cipher_descriptor[cipher].omac_memory(key, keylen, in, inlen, out, outlen); } /* allocate ram for omac state */ omac = XMALLOC(sizeof(omac_state)); if (omac == NULL) { return CRYPT_MEM; } /* omac process the message */ if ((err = omac_init(omac, cipher, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } if ((err = omac_process(omac, in, inlen)) != CRYPT_OK) { goto LBL_ERR; } if ((err = omac_done(omac, out, outlen)) != CRYPT_OK) { goto LBL_ERR; } err = CRYPT_OK; LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(omac, sizeof(omac_state)); #endif XFREE(omac); return err; }
/** LTC_OMAC a file @param cipher The index of the cipher desired @param key The secret key @param keylen The length of the secret key (octets) @param filename The name of the file you wish to LTC_OMAC @param out [out] Where the authentication tag is to be stored @param outlen [in/out] The max size and resulting size of the authentication tag @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled */ int omac_file(int cipher, const unsigned char *key, unsigned long keylen, const char *filename, unsigned char *out, unsigned long *outlen) { #ifdef LTC_NO_FILE return CRYPT_NOP; #else int err, x; omac_state omac; FILE *in; unsigned char buf[512]; LTC_ARGCHK(key != NULL); LTC_ARGCHK(filename != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); in = fopen(filename, "rb"); if (in == NULL) { return CRYPT_FILE_NOTFOUND; } if ((err = omac_init(&omac, cipher, key, keylen)) != CRYPT_OK) { fclose(in); return err; } do { x = fread(buf, 1, sizeof(buf), in); if ((err = omac_process(&omac, buf, x)) != CRYPT_OK) { fclose(in); return err; } } while (x == sizeof(buf)); fclose(in); if ((err = omac_done(&omac, out, outlen)) != CRYPT_OK) { return err; } #ifdef LTC_CLEAN_STACK zeromem(buf, sizeof(buf)); #endif return CRYPT_OK; #endif }
int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct, unsigned long length) { int err; _ARGCHK(eax != NULL); _ARGCHK(pt != NULL); _ARGCHK(ct != NULL); /* encrypt */ if ((err = ctr_encrypt(pt, ct, length, &eax->ctr)) != CRYPT_OK) { return err; } /* omac ciphertext */ return omac_process(&eax->ctomac, ct, length); }
int eax_addheader( const unsigned char hdr[], unsigned long length, eax_state eax[1] ) { return omac_process( hdr, length, eax->hdr_omac ); }
int eax_init( const unsigned char key[], unsigned long key_len, const unsigned char nonce[], unsigned long nonce_len, const unsigned char hdr[], unsigned long header_len, eax_state eax[1] ) { unsigned char *buf; int err = EXIT_FAILURE; omac_state *omac; unsigned long len; if( header_len > 0 && hdr == NULL ) goto exit3; if( ( buf = malloc( AES_BLOCK_SIZE ) ) == NULL ) goto exit3; if( ( omac = malloc( sizeof(*omac) ) ) == NULL ) goto exit2; memset( buf, 0, AES_BLOCK_SIZE ); if( (err = omac_init(key, key_len, omac)) != EXIT_SUCCESS ) goto exit1; if( (err = omac_process(buf, AES_BLOCK_SIZE, omac)) != EXIT_SUCCESS ) goto exit1; if( (err = omac_process(nonce, nonce_len, omac)) != EXIT_SUCCESS ) goto exit1; len = sizeof( eax->nv ); if( (err = omac_done(eax->nv, &len, omac)) != EXIT_SUCCESS ) goto exit1; memset( buf, 0, AES_BLOCK_SIZE ); buf[AES_BLOCK_SIZE - 1] = 1; if( (err = omac_init(key, key_len, eax->hdr_omac)) != EXIT_SUCCESS ) goto exit1; if( (err = omac_process(buf, AES_BLOCK_SIZE, eax->hdr_omac)) != EXIT_SUCCESS ) goto exit1; if( header_len != 0 && ( (err = omac_process(hdr, header_len, eax->hdr_omac) ) != EXIT_SUCCESS ) ) goto exit1; if( (err = ctr_start(eax->nv, key, key_len, 0, CTR_COUNTER_BIG_ENDIAN, eax->ctr) ) != EXIT_SUCCESS ) goto exit1; if( (err = omac_init(key, key_len, eax->ctx_omac)) != EXIT_SUCCESS ) goto exit1; memset( buf, 0, AES_BLOCK_SIZE ); buf[AES_BLOCK_SIZE - 1] = 2; if( (err = omac_process(buf, AES_BLOCK_SIZE, eax->ctx_omac)) != EXIT_SUCCESS ) goto exit1; err = EXIT_SUCCESS; exit1: free( omac ); exit2: free( buf ); exit3: return err; }