// ======================================================================================================== // ======================================================================================================== // ****************************************** verifier_common.c ******************************************* // ======================================================================================================== // ======================================================================================================== #include "common.h" #include "verifier_common.h" // ======================================================================================================== // ======================================================================================================== // Reads in the vector file. Format is first vector/second vector on two separate lines, followed by a blank // line, then repeat. Space for first_vecs and second_vecs is allocated in the caller. int ReadVectorAndMaskFiles(int str_length, char *vec_pair_path, int max_vecs, int vec_len_bits, int *num_rise_vecs_ptr, unsigned char *first_vecs_b[max_vecs], unsigned char *second_vecs_b[max_vecs], int has_masks, char *mask_file_path, int mask_len_bits, unsigned char *masks[max_vecs]) { int first_second_vec, vc, is_rising, is_falling, rise_or_fall; char first_vec[vec_len_bits+1], second_vec[vec_len_bits+1]; int byte_cnter, bit_cnter, mod_8_val; char line[str_length], *char_ptr; unsigned char *vec_ptr; int vec_pair_cnt; FILE *INFILE; if ( (INFILE = fopen(vec_pair_path, "r")) == NULL ) { printf("ERROR: ReadVectorAndMaskFiles(): Could not open VectorPair file %s\n", vec_pair_path); fflush(stdout); exit(EXIT_FAILURE); } // Sanity check. Make sure 'vec_len_bits' is evenly divisible by 8 otherwise the binary conversion routine below will NOT work. if ( (vec_len_bits % 8) != 0 ) { printf("ERROR: ReadVectorAndMaskFiles(): 'vec_len_bits' %d MUST be divisible by 8!\n", vec_len_bits); fflush(stdout); exit(EXIT_FAILURE); } if ( has_masks == 1 && (mask_len_bits % 8) != 0 ) { printf("ERROR: ReadVectorAndMaskFiles(): 'mask_len_bits' %d MUST be divisible by 8!\n", mask_len_bits); fflush(stdout); exit(EXIT_FAILURE); } vec_pair_cnt = 0; first_second_vec = 0; *num_rise_vecs_ptr = 0; rise_or_fall = -1; while ( fgets(line, str_length, INFILE) != NULL ) { // Find the newline and eliminate it. if ((char_ptr = strrchr(line, '\n')) != NULL) *char_ptr = '\0'; // Assume there is NO blank line as the first line in the file, and assume the last line is present but blank if ( strlen(line) == 0 ) { vec_pair_cnt++; continue; } // Sanity check if ( vec_pair_cnt >= max_vecs ) { printf("ERROR: ReadVectorAndMaskFiles(): Exceeded maximum number of vectors %d!\n", max_vecs); fflush(stdout); exit(EXIT_FAILURE); } // Sanity checks if ( strlen(line) != vec_len_bits ) { printf("ERROR: ReadVectorAndMaskFiles(): Unexpected vector size %d -- expected %d!\n", (int)strlen(line), vec_len_bits); fflush(stdout); exit(EXIT_FAILURE); } // Copy the first ASCII version of the vector into the stack allocated space + 1 (for NULL termination). if ( first_second_vec == 0 ) strcpy(first_vec, line); else { strcpy(second_vec, line); // Assume the vectors are constructed to be rising only or falling only. Find a transition in the vector pair that indicates rising, i.e., // 0 in first vector and 1 in second vector at that same position. vc = 0; is_rising = 0; is_falling = 0; while ( first_vec[vc] != '\0' ) { // Sanity check. if ( second_vec[vc] == '\0' ) { printf("ERROR: ReadVectorAndMaskFiles(): Vector pair at %d NOT the same length!\n", vec_pair_cnt); fflush(stdout); exit(EXIT_FAILURE); } // Count 1 for rising on the first rising transition. if ( first_vec[vc] == '0' && second_vec[vc] == '1' ) { // Check that we are not intermixing rising and falling vectors. If this is ever 1, then we processed a falling vector on a previous iteration, // which is an error. This requires rising vectors to preceed falling vectors. if ( rise_or_fall == 1 ) { printf("ERROR: ReadVectorAndMaskFiles(): Intermixing of rising and falling vectors illegal!\n"); fflush(stdout); exit(EXIT_FAILURE); } rise_or_fall = 0; // Error if both transitions are present. if ( is_falling == 1 ) { printf("ERROR: ReadVectorAndMaskFiles(): Found vector %d with BOTH rising and falling transitions!\n", vec_pair_cnt); fflush(stdout); exit(EXIT_FAILURE); } // Only count this vector as rising on the first occurance of a rising edge. if ( is_rising == 0 ) (*num_rise_vecs_ptr)++; is_rising = 1; } // Same check for falling transitions if ( first_vec[vc] == '1' && second_vec[vc] == '0' ) { // Indicate that we are processing falling vectors. if ( rise_or_fall == -1 ) { printf("ERROR: ReadVectorAndMaskFiles(): Expected rising vectors to be first in vector file!\n"); fflush(stdout); exit(EXIT_FAILURE); } rise_or_fall = 1; // Error if both transitions are present. if ( is_rising == 1 ) { printf("ERROR: ReadVectorAndMaskFiles(): Found vector %d with BOTH rising and falling transitions!\n", vec_pair_cnt); fflush(stdout); exit(EXIT_FAILURE); } is_falling = 1; } vc++; } } // ============================================= // Convert from ASCII to binary. Allocate space for binary unsigned char version of vectors. if ( first_second_vec == 0 ) { first_vecs_b[vec_pair_cnt] = (unsigned char *)malloc(sizeof(unsigned char)*vec_len_bits/8); vec_ptr = first_vecs_b[vec_pair_cnt]; } else { second_vecs_b[vec_pair_cnt] = (unsigned char *)malloc(sizeof(unsigned char)*vec_len_bits/8); vec_ptr = second_vecs_b[vec_pair_cnt]; } // DEBUG //printf("ReadVectorAndMaskFiles(): Binary vec for vec_pair_cnt %d\n\t", vec_pair_cnt); fflush(stdout); // ASCII version of vector processed from 0 to 'vec_len_bits' is high order to low order. Preserve this characteristics in the unsigned char binary // byte array by starting the load at the highest byte. NOTE: 'vec_len_bits' MUST BE DIVISIBLE BY 8 otherwise this code does not work properly, // which is checked above. byte_cnter = vec_len_bits/8 - 1; for ( bit_cnter = 0; bit_cnter < vec_len_bits; ) { // Sanity check if ( byte_cnter < 0 ) { printf("ERROR: ReadVectorAndMaskFiles(): Program error: 'byte_cnter' %d is LESS THAN 0!\n", byte_cnter); fflush(stdout); exit(EXIT_FAILURE); } mod_8_val = bit_cnter % 8; if ( mod_8_val == 0 ) vec_ptr[byte_cnter] = 0; // Keep adding in bits to the current byte at the appropriate bit position in the byte. Left to right processing of the line needs to make // the first (left-most) ASCII bit in the line the high order bit in the binary byte, i.e., preserve the high-order to low-order property // of the vector ASCII line. if ( line[bit_cnter] == '1' ) vec_ptr[byte_cnter] += (unsigned char)(1 << (7 - mod_8_val)); bit_cnter++; if ( (bit_cnter % 8) == 0 ) { // DEBUG //printf("%02X ", vec_ptr[byte_cnter]); fflush(stdout); byte_cnter--; } } // DEBUG //printf("\n"); fflush(stdout); // Each non-zero line has a vector, invert first or second vector indicator and add 1 to vec_pair_cnt first_second_vec = !first_second_vec; } fclose(INFILE); // Read in the mask file if specified if ( has_masks == 1 ) { int mask_vec; if ( (INFILE = fopen(mask_file_path, "r")) == NULL ) { printf("ERROR: ReadVectorAndMaskFiles(): Could not open Mask file %s\n", mask_file_path); fflush(stdout); exit(EXIT_FAILURE); } // We MUST find a mask for every vector read above. for ( mask_vec = 0; mask_vec < vec_pair_cnt; mask_vec++ ) { // Sanity check if ( fgets(line, str_length, INFILE) == NULL ) { printf("ERROR: ReadVectorAndMaskFiles(): A mask file is requested but number of masks does NOT equal number of vectors!\n"); fflush(stdout); exit(EXIT_FAILURE); } // Find the newline and eliminate it. if ((char_ptr = strrchr(line, '\n')) != NULL) *char_ptr = '\0'; // Allocate space for the mask (number of output_bits/8) masks[mask_vec] = (unsigned char *)malloc(sizeof(unsigned char)*mask_len_bits/8); // ASCII version of mask processed from 0 to 'mask_len_bits' is high order to low order. Preserve this characteristics in the unsigned char binary // byte array by starting the load at the highest byte. NOTE: 'mask_len_bits' MUST BE DIVISIBLE BY 8 otherwise this code does not work properly, // which is checked above. byte_cnter = mask_len_bits/8 - 1; for ( bit_cnter = 0; bit_cnter < mask_len_bits; ) { // Sanity check if ( byte_cnter < 0 ) { printf("ERROR: ReadVectorAndMaskFiles(): Program error: 'byte_cnter' %d is LESS THAN 0!\n", byte_cnter); fflush(stdout); exit(EXIT_FAILURE); } mod_8_val = bit_cnter % 8; if ( mod_8_val == 0 ) masks[mask_vec][byte_cnter] = 0; // Keep adding in bits to the current byte at the appropriate bit position in the byte. Left to right processing of the line needs to make // the first (left-most) ASCII bit in the line the high order bit in the binary byte, i.e., preserve the high-order to low-order property // of the vector ASCII line. if ( line[bit_cnter] == '1' ) masks[mask_vec][byte_cnter] += (unsigned char)(1 << (7 - mod_8_val)); bit_cnter++; if ( (bit_cnter % 8) == 0 ) { // DEBUG //printf("%02X ", masks[mask_vec][byte_cnter]); fflush(stdout); byte_cnter--; } } } fclose(INFILE); } return vec_pair_cnt; } // ======================================================================================================== // ======================================================================================================== // Send num_vecs and vector pairs to the token for ID phase enrollment. void SendVectorsAndMasks(int str_length, int num_vecs, int max_vecs, int token_socket_desc, int num_rise_vecs, int vec_len_bits, unsigned char *first_vecs_b[max_vecs], unsigned char *second_vecs_b[max_vecs], int has_masks, int mask_len_bits, unsigned char *masks[max_vecs]) { char num_vecs_str[str_length]; int i; // Send num_vecs first. sprintf(num_vecs_str, "%d %d %d", num_vecs, num_rise_vecs, has_masks); // Send num_bytes of string as two-binary bytes. When sending ASCII character strings, be sure to add one to include // the NULL termination character (+ 1) so the receiver can treat this as a string. if ( SockSendB((unsigned char *)num_vecs_str, strlen(num_vecs_str) + 1, token_socket_desc) < 0 ) { printf("ERROR: SendVectorsAndMasks(): Send '%s' failed\n", num_vecs_str); fflush(stdout); exit(EXIT_FAILURE); } // Send first_vecs and second_vecs to remote server for ( i = 0; i < num_vecs; i++ ) { if ( SockSendB(first_vecs_b[i], vec_len_bits/8, token_socket_desc) < 0 ) { printf("ERROR: SendVectorsAndMasks(): Send 'first_vecs_b[%d]' failed\n", i); fflush(stdout); exit(EXIT_FAILURE); } if ( SockSendB(second_vecs_b[i], vec_len_bits/8, token_socket_desc) < 0 ) { printf("ERROR: SendVectorsAndMasks(): Send 'second_vecs_b[%d]' failed\n", i); fflush(stdout); exit(EXIT_FAILURE); } if ( has_masks == 1 && SockSendB(masks[i], mask_len_bits/8, token_socket_desc) < 0 ) { printf("ERROR: SendVectorsAndMasks(): Send 'masks[%d]' failed\n", i); fflush(stdout); exit(EXIT_FAILURE); } } // DEBUG //printf("SendVectorsAndMasks(): Sent %d vector pairs!\n", num_vecs); fflush(stdout); return; }