# Authentication

# Login

The login function authenticates the user by takin in a username and pin. The function checks if the username matches any existing user stored on the player, generates a hash from the input pin, and compares it to the hash stored under the aforementioned user's secret struct within the player. The pin is hashed with argon2id, using 16-byte random salts, and is iterated 3 times.

void login() {
    if (s.logged_in) {
        mb_printf("Already logged in. Please log out first.\r\n");
        memcpy((void*)c->username, s.username, USERNAME_SZ);
        memcpy((void*)c->pin, s.pin, MAX_PIN_SZ);
    } else {
        for (int i = 0; i < PROVISIONED_USERS; i++) {
            // search for matching username
            if (!strcmp((void*)c->username, user_data[i].name)) {
                // check if pin matches
            	//secrets pin hash to bytes
            	uint8_t usr_pin_bytes[ARGON_HASH_SZ] = {0};
            	byte_me(usr_pin_bytes, user_data[i].pin_hash, strlen(user_data[i].pin_hash));
            	//
            	//make comparison hash
            	uint8_t cmp_hash[ARGON_HASH_SZ] = {0};
            	//work area
            	uint8_t *work_area;
            	work_area = (uint8_t *) malloc(ARGON_BLOCKS*1024);
            	crypto_wipe(work_area, sizeof(work_area);
            	if (work_area == NULL)
            	{
            		mb_printf("\r\nFailed to allocate the work area. Aborting.\r\n");
            		crypto_wipe((void*)c->username, USERNAME_SZ);
                    crypto_wipe((void*)c->pin, MAX_PIN_SZ);
            		return;
            	}
            	//salt bytes
            	uint8_t salt_bytes[ARGON_SALT_SZ] = {0};
            	byte_me(salt_bytes, user_data[i].salt, strlen(user_data[i].salt));
                crypto_argon2i(cmp_hash,
            				   ARGON_HASH_SZ,
							   work_area,
							   ARGON_BLOCKS,
							   ARGON_ITTERS,
							   (void*)c->pin,
							   strlen((void*)c->pin),
							   salt_bytes,
							   ARGON_SALT_SZ);
                if (!crypto_verify32(cmp_hash, usr_pin_bytes)) {
                    //update states
                    s.logged_in = 1;
                    c->login_status = 1;
                    memcpy(s.username, (void*)c->username, USERNAME_SZ);
                    memcpy(s.pin, (void*)c->pin, MAX_PIN_SZ);
                    s.uid = user_data[i].id;
                    mb_printf("Logged in for user '%s'\r\n", c->username);
                    free(work_area);
                    return;
                } else {
                    // reject login attempt
                    mb_printf("Incorrect pin for user '%s'\r\n", c->username);
                    crypto_wipe((void*)c->username, USERNAME_SZ);
                    crypto_wipe((void*)c->pin, MAX_PIN_SZ);
                    free(work_area);
                    return;
                }
            }
        }

        // reject login attempt
        mb_printf("User not found\r\n");
        crypto_wipe((void*)c->username, USERNAME_SZ);
        crypto_wipe((void*)c->pin, MAX_PIN_SZ);
    }
}

# Logout

The logout function terminates a user's session on the miPod if and only if they are first logged in. This function zeros out the command channel c of all references to the user, changes the miPod's internal state s.logged_in to 0, has no parameters, and returns void.

void logout() {
    if (c->login_status) {
        mb_printf("Logging out...\r\n");
        s.logged_in = 0;
        c->login_status = 0;
        memset((void*)c->username, 0, USERNAME_SZ);
        memset((void*)c->pin, 0, MAX_PIN_SZ);
        s.uid = 0;
    } else {
        mb_printf("Not logged in\r\n");
    }
}
Last Updated: 4/24/2020, 10:45:59 PM