summaryrefslogtreecommitdiff
path: root/cleopatre/application/libspid/src/secu.c
blob: d2be8eb2b820487b8004803b9e5b11755576db56 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/* Cesar project {{{
 *
 * Copyright (C) 2009 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */
/**
 * \file    application/libspid/src/secu.c
 * \brief   security functions
 * \ingroup libspid
 *
 * Utilities to generate keys and manage security stuffs
 */

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "libspid.h"

static void
libspid_secu_sha256 (unsigned char *data, unsigned int length, unsigned char *output)
{
    assert (data);
    assert (output);

    output = SHA256(data, length, output);
}

static void
secu_pbkdf1 (const unsigned char input[], const unsigned int input_length,
             const unsigned char salt[LIBSPID_SECU_SALT_SIZE],
             const unsigned int it_count, unsigned char output[],
             unsigned int output_length)
{

     /* Check parameters. */
    assert (input);
    assert (input_length);
    assert (salt);
    assert (it_count);
    assert (output);
    assert (output_length);

    /* Maximum size of dk. */
    unsigned char dk[LIBSPID_SECU_PWD_SIZE_MAX + LIBSPID_SECU_SALT_SIZE]
        __attribute__((aligned(128)));
    unsigned char sha_output[LIBSPID_SECU_SHA256_SIZE]
        __attribute__((aligned(128)));

    memset (dk, 0, sizeof (dk));
    memset (sha_output, 0, sizeof (sha_output));

    /* Concatenate input and salt. */
    /* Add input. */
    memcpy (dk, input, input_length);
    /* If there is a salt, add it at the end. */
    if (salt)
        memcpy (dk + input_length, salt, LIBSPID_SECU_SALT_SIZE);

    /* Compute the first derived key with sha256. */
    libspid_secu_sha256 (dk, input_length + (salt ? LIBSPID_SECU_SALT_SIZE : 0),
                    sha_output);
    /* Compute the following iterations. */
    unsigned int i;
    for (i = 1; i < it_count; i++)
    {
        libspid_secu_sha256 (sha_output, LIBSPID_SECU_SHA256_SIZE, sha_output);
    }
    /* Copy only LIBSPID_SECU_OUTPUT_KEY_SIZE as result. */

    memcpy (output, sha_output, output_length);
}


/**
 * Compute a key with pbkdf1 algorithm. Key is provided inside the
 * input buffer, with the key length inside input_length.
 * Salt and iteration number must be also provided.
 * Result key is put inside output buffer, with its size known by
 * output_length.
 *
 * \param input buffer where is the key to hash
 * \param input_length key length inside the buffer
 * \param salt_type salt type for key generation
 * \param it_count number of iteration to process
 * \param output buffer where is stored the result hash
 * \param output_length length of buffer where to store the result hash
 * \return error type (LIBSPID_SUCCESS if success)
 * \return LIBSPID_ERROR_PARAM: bad input parameters
 */
libspid_error_t libspid_secu_pbkdf1 (const unsigned char input[], const unsigned int input_length, const libspid_secu_salt_type_t salt_type, const unsigned int it_count, unsigned char output[], unsigned int output_length)
{
    unsigned char *pbkdf1;
    /* The salt to use for the PBKDF1 function. */
    unsigned char salt[LIBSPID_SECU_SALT_SIZE] = {0x08, 0x85, 0x6d, 0xaf, 0x7c, 0xf5, 0x81, 0x00};

    /* Check parameters. */
    if((NULL == input) || (0 == input_length)
       || (salt_type >= LIBSPID_SECU_SALT_TYPE_NB)
       || (0 == it_count) || (NULL == output) || (0 == output_length))
    {
        return LIBSPID_ERROR_PARAM;
    }

    switch (salt_type)
    {
    case LIBSPID_SECU_SALT_TYPE_DAK:
        salt[7] = 0x85;
        pbkdf1 = salt;
        break;
    case LIBSPID_SECU_SALT_TYPE_NMK:
        salt[7] = 0x86;
        pbkdf1 = salt;
        break;
    case LIBSPID_SECU_SALT_TYPE_NONE:
    default:
        pbkdf1 = NULL;
        break;
    }

    secu_pbkdf1 (input, input_length,
                 pbkdf1, it_count,
                 output, output_length);
    return LIBSPID_SUCCESS;
}