~ubuntu-branches/ubuntu/utopic/moonshot-gss-eap/utopic-backports

« back to all changes in this revision

Viewing changes to libeap/src/crypto/aes-unwrap.c

  • Committer: Package Import Robot
  • Author(s): Sam Hartman
  • Date: 2014-09-16 08:38:39 UTC
  • Revision ID: package-import@ubuntu.com-20140916083839-ipqco3thb1wcwvs0
Tags: upstream-0.9.2
ImportĀ upstreamĀ versionĀ 0.9.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * AES key unwrap (128-bit KEK, RFC3394)
 
3
 *
 
4
 * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License version 2 as
 
8
 * published by the Free Software Foundation.
 
9
 *
 
10
 * Alternatively, this software may be distributed under the terms of BSD
 
11
 * license.
 
12
 *
 
13
 * See README and COPYING for more details.
 
14
 */
 
15
 
 
16
#include "includes.h"
 
17
 
 
18
#include "common.h"
 
19
#include "aes.h"
 
20
#include "aes_wrap.h"
 
21
 
 
22
/**
 
23
 * aes_unwrap - Unwrap key with AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
 
24
 * @kek: Key encryption key (KEK)
 
25
 * @n: Length of the plaintext key in 64-bit units; e.g., 2 = 128-bit = 16
 
26
 * bytes
 
27
 * @cipher: Wrapped key to be unwrapped, (n + 1) * 64 bits
 
28
 * @plain: Plaintext key, n * 64 bits
 
29
 * Returns: 0 on success, -1 on failure (e.g., integrity verification failed)
 
30
 */
 
31
int aes_unwrap(const u8 *kek, int n, const u8 *cipher, u8 *plain)
 
32
{
 
33
        u8 a[8], *r, b[16];
 
34
        int i, j;
 
35
        void *ctx;
 
36
 
 
37
        /* 1) Initialize variables. */
 
38
        os_memcpy(a, cipher, 8);
 
39
        r = plain;
 
40
        os_memcpy(r, cipher + 8, 8 * n);
 
41
 
 
42
        ctx = aes_decrypt_init(kek, 16);
 
43
        if (ctx == NULL)
 
44
                return -1;
 
45
 
 
46
        /* 2) Compute intermediate values.
 
47
         * For j = 5 to 0
 
48
         *     For i = n to 1
 
49
         *         B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i
 
50
         *         A = MSB(64, B)
 
51
         *         R[i] = LSB(64, B)
 
52
         */
 
53
        for (j = 5; j >= 0; j--) {
 
54
                r = plain + (n - 1) * 8;
 
55
                for (i = n; i >= 1; i--) {
 
56
                        os_memcpy(b, a, 8);
 
57
                        b[7] ^= n * j + i;
 
58
 
 
59
                        os_memcpy(b + 8, r, 8);
 
60
                        aes_decrypt(ctx, b, b);
 
61
                        os_memcpy(a, b, 8);
 
62
                        os_memcpy(r, b + 8, 8);
 
63
                        r -= 8;
 
64
                }
 
65
        }
 
66
        aes_decrypt_deinit(ctx);
 
67
 
 
68
        /* 3) Output results.
 
69
         *
 
70
         * These are already in @plain due to the location of temporary
 
71
         * variables. Just verify that the IV matches with the expected value.
 
72
         */
 
73
        for (i = 0; i < 8; i++) {
 
74
                if (a[i] != 0xa6)
 
75
                        return -1;
 
76
        }
 
77
 
 
78
        return 0;
 
79
}