int crypto_aead_decrypt( unsigned char *m, size_t *mlen, const unsigned char *h, size_t hlen, const unsigned char *c, size_t clen, const unsigned char *nonce, const unsigned char *key ) { int result = -1; unsigned char tag[BYTES(MRS_T)]; mrs_state_t state; if (clen < BYTES(MRS_T)) { return -1; } /* decryption phase */ mrs_init(state, key, c + clen - BYTES(MRS_T), WORDS(MRS_T), ENC_TAG); /* initialise with key and authentication tag */ mrs_decrypt_data(state, m, c, clen - BYTES(MRS_T)); *mlen = clen - BYTES(MRS_T); /* absorption phase */ mrs_init(state, key, nonce, WORDS(MRS_N), ABS_TAG); mrs_absorb_data(state, h, hlen); mrs_absorb_data(state, m, *mlen); mrs_finalise(state, hlen, *mlen, tag); /* verification phase */ result = mrs_verify_tag(c + clen - BYTES(MRS_T), tag); /* burn decrypted plaintext on authentication failure */ if(result != 0) { burn(m, 0, *mlen); } burn(state, 0, sizeof(mrs_state_t)); return result; }
static NORX_INLINE void norx_decrypt_lastblock(norx_state_t state, uint8_t *out, const uint8_t * in, size_t inlen) { norx_word_t * S = state->S; uint8_t lastblock[BYTES(NORX_R)]; size_t i; S[15] ^= PAYLOAD_TAG; norx_permute(state); for(i = 0; i < WORDS(NORX_R); ++i) { STORE(lastblock + i * BYTES(NORX_W), S[i]); } memcpy(lastblock, in, inlen); lastblock[inlen] ^= 0x01; lastblock[BYTES(NORX_R) - 1] ^= 0x80; for (i = 0; i < WORDS(NORX_R); ++i) { const norx_word_t c = LOAD(lastblock + i * BYTES(NORX_W)); STORE(lastblock + i * BYTES(NORX_W), S[i] ^ c); S[i] = c; } memcpy(out, lastblock, inlen); burn(lastblock, 0, sizeof lastblock); }
static MRS_INLINE void mrs_decrypt_lastblock(mrs_state_t state, unsigned char * out, const unsigned char * in, size_t inlen) { size_t i; mrs_word_t * S = state->S; uint8_t lastblock[BYTES(MRS_R)]; mrs_permute(state); for(i = 0; i < WORDS(MRS_R); ++i) { STORE(lastblock + i * BYTES(MRS_W), S[i]); } /* undo padding */ memcpy(lastblock, in, inlen); /*lastblock[inlen] ^= 0x01; lastblock[BYTES(MRS_R) - 1] ^= 0x80;*/ for (i = 0; i < WORDS(MRS_R); ++i) { const mrs_word_t c = LOAD(lastblock + i * BYTES(MRS_W)); STORE(lastblock + i * BYTES(MRS_W), S[i] ^ c); S[i] = c; } memcpy(out, lastblock, inlen); #if defined(MRS_DEBUG) printf("DECRYPTING LASTBLOCK:\n"); print_bytes(lastblock, BYTES(MRS_R)); printf("STATE:\n"); print_state(state->S); #endif burn(lastblock, 0, sizeof lastblock); }
void mrs_finalise(mrs_state_t state, size_t hlen, size_t mlen, unsigned char * tag) { mrs_word_t * S = state->S; uint8_t lastblock[BYTES(MRS_R)]; size_t i; /* finalise state */ mrs_permute(state); S[0] ^= hlen; S[1] ^= mlen; mrs_permute(state); /* extract tag */ for (i = 0; i < WORDS(MRS_R); ++i) { STORE(lastblock + i * BYTES(MRS_W), S[i]); } memcpy(tag, lastblock, BYTES(MRS_T)); #if defined(MRS_DEBUG) printf("FINALISED:\n"); print_state(state->S); #endif burn(lastblock, 0, BYTES(MRS_R)); }
static NORX_INLINE void norx_decrypt_lastblock(norx_state_t state, uint8_t *out, const uint8_t * in, size_t inlen) { norx_word_t * S = state->S; uint8_t b[BYTES(NORX_W)]; size_t i, j; norx_inject_tag(state, PAYLOAD_TAG); norx_permutation(state); /* Undo padding */ S[inlen / BYTES(NORX_W)] ^= 0x01ULL << ((inlen % BYTES(NORX_W)) * 8); S[WORDS(RATE) - 1] ^= 0x80ULL << (((BYTES(RATE) - 1) % BYTES(NORX_W)) * 8); for(i = 0; inlen >= BYTES(NORX_W); ++i) { norx_word_t c = LOAD(in); STORE(out, S[i] ^ c); S[i] = c; inlen -= BYTES(NORX_W); in += BYTES(NORX_W); out += BYTES(NORX_W); } STORE(b, S[i]); for(j = 0; j < inlen; ++j) { uint8_t c = in[j]; out[j] = b[j] ^ c; b[j] = c; } S[i] = LOAD(b); }
/* We need Unicode versions of these. */ PolyWord C_string_to_Poly(TaskData *mdTaskData, const WCHAR *buffer) /* Returns a Unicode string as a Poly string. */ { if (buffer == NULL) return EmptyString(); // Get the length of the string, without the terminating null. int buffLen = (int)wcslen(buffer); if (buffLen == 0) return EmptyString(); // If it's zero return empty string. // Find the length when converted. int outputLen = WideCharToMultiByte(codePage, 0, buffer, buffLen, NULL, 0, NULL, NULL); // Return the null string if there's an error if (outputLen <= 0) return EmptyString(); // Return the character itself if the length is 1 */ if (outputLen == 1) { char obuff[1]; int check = WideCharToMultiByte(codePage, 0, buffer, buffLen, obuff, 1, NULL, NULL); if (check <= 0) return EmptyString(); return TAGGED(obuff[0]); } // Get the number of words required, plus 1 for length word, plus flag bit. PolyStringObject *result = (PolyStringObject *)(alloc(mdTaskData, WORDS(outputLen) + 1, F_BYTE_OBJ)); // Set length of string, then copy the characters. result->length = outputLen; int check = WideCharToMultiByte(codePage, 0, buffer, buffLen, result->chars, outputLen, NULL, NULL); if (check <= 0) return EmptyString(); return result; }
char *build_request(t_words w) { int i; char *buffer = NULL; int size = 0; for(i=0;i<NBR_WORDS(w);i++) { int ln = strlen(WORDS(w)[i]); char *lbuff = malloc((ln+2)*sizeof(char)); if (lbuff == NULL) { FATAL("Erreur d'allocation mémoire : %s", strerror(errno)); exit(100); } sprintf(lbuff, "%s+", WORDS(w)[i]); buffer = realloc_word(buffer, lbuff, size, ln+1); size += ln+1; free(lbuff); } return buffer; }
static NORX_INLINE void norx_absorb_block(norx_state_t state, const uint8_t * in, tag_t tag) { size_t i; norx_word_t * S = state->S; S[15] ^= tag; norx_permute(state); for (i = 0; i < WORDS(NORX_R); ++i) { S[i] ^= LOAD(in + i * BYTES(NORX_W)); } }
static NORX_INLINE void norx_encrypt_block(norx_state_t state, uint8_t *out, const uint8_t * in) { size_t i; norx_word_t * S = state->S; S[15] ^= PAYLOAD_TAG; norx_permute(state); for (i = 0; i < WORDS(NORX_R); ++i) { S[i] ^= LOAD(in + i * BYTES(NORX_W)); STORE(out + i * BYTES(NORX_W), S[i]); } }
/* high level interface functions */ void crypto_aead_encrypt( unsigned char *c, size_t *clen, const unsigned char *h, size_t hlen, const unsigned char *m, size_t mlen, const unsigned char *nonce, const unsigned char *key ) { mrs_state_t state; /* absorption phase */ mrs_init(state, key, nonce, WORDS(MRS_N), ABS_TAG); mrs_absorb_data(state, h, hlen); mrs_absorb_data(state, m, mlen); mrs_finalise(state, hlen, mlen, c + mlen); *clen = mlen + BYTES(MRS_T); /* encryption phase */ mrs_init(state, key, c + mlen, WORDS(MRS_T), ENC_TAG); /* re-initialise with key and authentication tag */ mrs_encrypt_data(state, c, m, mlen); burn(state, 0, sizeof(mrs_state_t)); }
void norx_output_tag(norx_state_t state, unsigned char * tag) { norx_word_t * S = state->S; uint8_t lastblock[BYTES(RATE)]; size_t i; norx_finalize(state); for (i = 0; i < WORDS(RATE); ++i) STORE(lastblock + i * BYTES(NORX_W), S[i]); memcpy(tag, lastblock, BYTES(NORX_A)); burn(lastblock, 0, BYTES(RATE)); /* burn full state dump */ burn(state, 0, sizeof(norx_state_t)); /* at this point we can also burn the state */ }
static NORX_INLINE void norx_decrypt_block(norx_state_t state, uint8_t *out, const uint8_t * in) { norx_word_t * S = state->S; size_t i; norx_inject_tag(state, PAYLOAD_TAG); norx_permutation(state); for (i = 0; i < WORDS(RATE); ++i) { const norx_word_t c = LOAD(in + i * BYTES(NORX_W)); STORE(out + i * BYTES(NORX_W), S[i] ^ c); S[i] = c; } }
static MRS_INLINE void mrs_absorb_block(mrs_state_t state, const unsigned char * in) { size_t i; mrs_word_t * S = state->S; mrs_permute(state); for (i = 0; i < WORDS(MRS_B); ++i) { S[i] ^= LOAD(in + i * BYTES(MRS_W)); } #if defined(MRS_DEBUG) printf("ABSORBING BLOCK:\n"); print_bytes(in, BYTES(MRS_B)); printf("STATE:\n"); print_state(state->S); #endif }
static NORX_INLINE void norx_absorb(norx_state_t state, const uint8_t * in, tag_t tag) { norx_word_t * S = state->S; size_t i; norx_inject_tag(state, tag); norx_permutation(state); #if defined(NORX_DEBUG) if (tag == HEADER_TAG) { printf("End of initialisation:\n"); norx_print_state(state); } #endif for (i = 0; i < WORDS(RATE); ++i) S[i] ^= LOAD(in + i * BYTES(NORX_W)); }
static MRS_INLINE void mrs_encrypt_block(mrs_state_t state, unsigned char * out, const unsigned char * in) { size_t i; mrs_word_t * S = state->S; mrs_permute(state); for (i = 0; i < WORDS(MRS_R); ++i) { S[i] ^= LOAD(in + i * BYTES(MRS_W)); STORE(out + i * BYTES(MRS_W), S[i]); } #if defined(MRS_DEBUG) printf("ENCRYPTING BLOCK:\n"); print_bytes(in, BYTES(MRS_R)); printf("STATE:\n"); print_state(state->S); #endif }
static NORX_INLINE void norx_encrypt_block(norx_state_t state, uint8_t *out, const uint8_t * in) { norx_word_t * S = state->S; size_t i; norx_inject_tag(state, PAYLOAD_TAG); norx_permutation(state); #if defined(NORX_DEBUG) && NORX_D == 1 printf("End of header processing \n"); norx_print_state(state); #endif for (i = 0; i < WORDS(RATE); ++i) { S[i] ^= LOAD(in + i * BYTES(NORX_W)); STORE(out + i * BYTES(NORX_W), S[i]); } }
PolyWord Buffer_to_Poly(TaskData *mdTaskData, const char *buffer, size_t length) /* Returns a string as a Poly string. */ { /* Return the null string if it's empty. */ if (length == 0) return EmptyString(); /* Return the character itself if the length is 1 */ if (length == 1) return TAGGED(((unsigned char *)buffer)[0]); /* Get the number of words required, plus 1 for length word, plus flag bit. */ PolyStringObject *result = (PolyStringObject *)(alloc(mdTaskData, WORDS(length) + 1, F_BYTE_OBJ)); /* Set length of string, then copy the characters. */ result->length = length; memcpy(result->chars,buffer,length); /* We are relying on alloc zeroing any unused bytes in the allocated store. That's essential for structure equality to work properly since it compares ALL bytes in a byte segment. (c.f. test*/ return result; } /* Buffer_to_Poly */
/* We need Unicode versions of these. */ PolyWord C_string_to_Poly(const WCHAR *buffer) /* Returns a Unicode string as a Poly string. */ { if (buffer == NULL) return EmptyString(); unsigned long length = wcslen(buffer); /* Return the null string if it's empty. */ if (length == 0) return EmptyString(); /* Return the character itself if the length is 1 */ if (length == 1) return TAGGED(((unsigned char *)buffer)[0]); /* Get the number of words required, plus 1 for length word, plus flag bit. */ PolyStringObject *result = (PolyStringObject *)(alloc(WORDS(length) + 1, F_BYTE_OBJ)); /* Set length of string, then copy the characters. */ result->length = length; for (unsigned long i = 0; i < length; i++) result->chars[i] = (char)buffer[i]; return result; } /* C_string_to_Poly */
static NORX_INLINE void norx_finalise(norx_state_t state, unsigned char * tag) { size_t i; norx_word_t * S = state->S; uint8_t lastblock[BYTES(NORX_R)]; S[15] ^= FINAL_TAG; norx_permute(state); norx_permute(state); for (i = 0; i < WORDS(NORX_R); ++i) { STORE(lastblock + i * BYTES(NORX_W), S[i]); } memcpy(tag, lastblock, BYTES(NORX_T)); #if defined(NORX_DEBUG) printf("Finalise\n"); norx_debug(state, NULL, 0, NULL, 0); #endif burn(lastblock, 0, BYTES(NORX_R)); /* burn full state dump */ burn(state, 0, sizeof(norx_state_t)); /* at this point we can also burn the state */ }
# define PAGE_SIZE 0x2000 # else # define PAGE_SIZE 0x1000 # endif #else #define PAGE_SIZE getpagesize() #endif #define ELIB_EXPAND(need) expand_sbrk(need) static FUNCTION(int, expand_sbrk, (EWord)); #elif defined(ELIB_HEAP_FIXED) #define PAGE_SIZE 1024 #define ELIB_EXPAND(need) -1 static EWord fix_heap[WORDS(ELIB_HEAP_SIZE)]; #elif defined(ELIB_HEAP_USER) #define PAGE_SIZE 1024 #define ELIB_EXPAND(need) -1 #else #error "ELIB HEAP TYPE NOT SET" #endif #define STAT_ALLOCED_BLOCK(SZ) \ do { \