summaryrefslogtreecommitdiff
path: root/cleopatre/application/libspid/src/secu.c
blob: adfde44c0b8ca977b74ce2ba64abe3f1fa31f2fe (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
129
130
131
132
133
134
/* 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;
}