~ubuntu-branches/ubuntu/natty/freeradius/natty-updates

« back to all changes in this revision

Viewing changes to src/modules/rlm_otp/otp_x99.c

  • Committer: Bazaar Package Importer
  • Author(s): Paul Hampson
  • Date: 2006-01-15 13:34:13 UTC
  • mto: (3.1.3 dapper) (4.1.3 sid) (1.1.14 upstream)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20060115133413-zo1dslttvdoalqym
Tags: upstream-1.1.0
ImportĀ upstreamĀ versionĀ 1.1.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * otp_x99.c
 
3
 * $Id: otp_x99.c,v 1.7.2.1 2005/12/08 01:30:53 fcusack Exp $
 
4
 *
 
5
 *   This program is free software; you can redistribute it and/or modify
 
6
 *   it under the terms of the GNU General Public License as published by
 
7
 *   the Free Software Foundation; either version 2 of the License, or
 
8
 *   (at your option) any later version.
 
9
 *
 
10
 *   This program is distributed in the hope that it will be useful,
 
11
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 *   GNU General Public License for more details.
 
14
 *
 
15
 *   You should have received a copy of the GNU General Public License
 
16
 *   along with this program; if not, write to the Free Software
 
17
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
18
 *
 
19
 * Copyright 2001,2002  Google, Inc.
 
20
 * Copyright 2005 TRI-D Systems, Inc.
 
21
 */
 
22
 
 
23
#include "otp.h"
 
24
 
 
25
#include <string.h>
 
26
#include <openssl/des.h>
 
27
 
 
28
static const char rcsid[] = "$Id: otp_x99.c,v 1.7.2.1 2005/12/08 01:30:53 fcusack Exp $";
 
29
 
 
30
 
 
31
/*
 
32
 * The ANSI X9.9 MAC algorithm is:
 
33
 * 1. Perform a CBC mode DES encryption of the plaintext.  The last plaintext
 
34
 *    block must be zero padded.
 
35
 * 2. The MAC is the most significant 32 bits of the last cipherblock.
 
36
 *
 
37
 * Most tokens support a max of an 8 character challenge, but at least one
 
38
 * (CRYPTOCard RB-1) supports performing the full CBC mode encryption
 
39
 * of an arbitrary length challenge.  So we don't limit ourselves
 
40
 * to just an ECB mode encryption.
 
41
 *
 
42
 * This routine returns the entire 64 bit last cipherblock, at least one sync
 
43
 * mode needs this (and ANSI X9.9 states that the MAC can be 48, and 64 bit
 
44
 * MACs should be supported).  Returns 0 on success, non-zero otherwise.
 
45
 */
 
46
int
 
47
otp_x99_mac(const unsigned char *input, size_t len, unsigned char output[8],
 
48
            const unsigned char keyblock[OTP_MAX_KEY_LEN],
 
49
            const char *log_prefix)
 
50
{
 
51
  des_key_schedule ks;
 
52
  des_cblock ivec;
 
53
  des_cblock l_output[OTP_MAX_CHALLENGE_LEN / sizeof(des_cblock)];
 
54
  int rc;
 
55
 
 
56
  /*
 
57
   * Setup and verify the key.
 
58
   * This may be a bit expensive to do every time, but it
 
59
   * makes more sense for calling functions to deal with
 
60
   * the key itself, rather than the schedule.  In practice,
 
61
   * I don't think this will amount to much, but I haven't
 
62
   * actually profiled it.
 
63
   * TODO: store in card_info after generating
 
64
   */
 
65
  if ((rc = des_set_key_checked((const_des_cblock *) keyblock, ks)) != 0) {
 
66
    otp_log(OTP_LOG_ERR, "%s: %s: otp_x99_mac: DES key %s",
 
67
            log_prefix, __func__,
 
68
            rc == -1 ? "has incorrect parity" : "is weak");
 
69
    return -1;
 
70
  }
 
71
 
 
72
  (void) memset(ivec, 0, sizeof(ivec));
 
73
  des_cbc_encrypt(input, (unsigned char *) l_output, len,
 
74
                  ks, &ivec, DES_ENCRYPT);
 
75
  (void) memcpy(output, l_output[(len - 1) / 8], 8);
 
76
  return 0;
 
77
}