Skip to content
Snippets Groups Projects
encryption_selfdestruct_post.c 2.98 KiB
Newer Older
/**
 * Destroy all active keyslots.
 * @param[in]   request   incoming HTTP request
 * @param[out]  response  HTTP response to the request
 * @param[in]   user_data extra data to pass between handler and main thread
 * @return                internal status code
 */
int destroy_active_keyslots()
{
    int r;

    // Initialise encrypted container.
    struct crypt_device * cd = NULL;
    r = container_initialise(&cd, DATA_PARTITION_DEVICE, true);
    if (r < 0)
    {
        crypt_free(cd);
    }
    if (r != 0)
    {
        return r;
    }

    // Determine number of keyslots.
    int keyslot_max = crypt_keyslot_max(CRYPT_LUKS1);
    int result = 0;
    if (keyslot_max >= 0)
    {
        // Destroy all active keyslots.
        int i;
        crypt_keyslot_info ki;
        for (i = 0; i < keyslot_max; i++)
        {
            ki = crypt_keyslot_status(cd, i);
            if (ki == CRYPT_SLOT_ACTIVE || ki == CRYPT_SLOT_ACTIVE_LAST)
            {
                r = crypt_keyslot_destroy(cd, i);
                if (r == 0)
                {
                    y_log_message(Y_LOG_LEVEL_DEBUG,
                        "keyslot %d destroyed succesfully",
                        i);
                }
                else
                {
                    y_log_message(Y_LOG_LEVEL_ERROR,
                        "failed to destroy keyslot %d",
                        i);
/**
 * Callback function for destroying the data on an encrypted device.
 * It does so by destroying all active keyslots.
 * Also, as an extra safety measure, it then overwrites the luks header and
 * keyslot area with zeroes.
 * See https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions:
 *     5.4 How do I securely erase a LUKS (or other) partition?
 * @param[in]   request   incoming HTTP request
 * @param[out]  response  HTTP response to the request
 * @param[in]   user_data extra data to pass between handler and main thread
 * @return                internal status code
 */
int callback_encryption_selfdestruct_post(const struct _u_request * request,
    struct _u_response * response, void * user_data)
{
    bool * shutdown = (bool *)user_data;
    destroy_active_keyslots();

    // Overwrite start of data partition with zeroes.
    y_log_message(Y_LOG_LEVEL_DEBUG,
Arie Peterson's avatar
Arie Peterson committed
        "Overwriting start of data partition with zeroes");
    char * command = NULL;
    asprintf(&command, "head -c %d /dev/zero > %s; sync",
        LUKS_HEADER_SIZE, DATA_PARTITION_DEVICE);
    r = system(command);
    if (r != 0)
    {
        y_log_message(Y_LOG_LEVEL_ERROR,
            "overwriting data device failed: return code %d",
            r);
        return send_simple_response(response, 500, "error",
            "overwriting data device failed");
    }

    // Record that we want to shut down the machine.
    *shutdown = true;

    r = send_simple_response(response, 200, "status", "ok");
    stop_server();
    return r;
}