jdk/src/share/native/sun/security/ec/ec.c
author vinnie
Tue, 11 Aug 2009 16:52:26 +0100
changeset 3492 e549cea58864
child 3636 b80fdcc0b0d5
permissions -rw-r--r--
6840752: Provide out-of-the-box support for ECC algorithms Reviewed-by: alanb, mullan, wetmore
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3492
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
     1
/* *********************************************************************
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
     2
 *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
     3
 * Sun elects to have this file available under and governed by the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
     4
 * Mozilla Public License Version 1.1 ("MPL") (see
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
     5
 * http://www.mozilla.org/MPL/ for full license text). For the avoidance
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
     6
 * of doubt and subject to the following, Sun also elects to allow
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
     7
 * licensees to use this file under the MPL, the GNU General Public
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
     8
 * License version 2 only or the Lesser General Public License version
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
     9
 * 2.1 only. Any references to the "GNU General Public License version 2
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    10
 * or later" or "GPL" in the following shall be construed to mean the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    11
 * GNU General Public License version 2 only. Any references to the "GNU
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    12
 * Lesser General Public License version 2.1 or later" or "LGPL" in the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    13
 * following shall be construed to mean the GNU Lesser General Public
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    14
 * License version 2.1 only. However, the following notice accompanied
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    15
 * the original version of this file:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    16
 *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    17
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    18
 *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    19
 * The contents of this file are subject to the Mozilla Public License Version
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    20
 * 1.1 (the "License"); you may not use this file except in compliance with
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    21
 * the License. You may obtain a copy of the License at
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    22
 * http://www.mozilla.org/MPL/
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    23
 *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    24
 * Software distributed under the License is distributed on an "AS IS" basis,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    25
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    26
 * for the specific language governing rights and limitations under the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    27
 * License.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    28
 *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    29
 * The Original Code is the Elliptic Curve Cryptography library.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    30
 *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    31
 * The Initial Developer of the Original Code is
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    32
 * Sun Microsystems, Inc.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    33
 * Portions created by the Initial Developer are Copyright (C) 2003
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    34
 * the Initial Developer. All Rights Reserved.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    35
 *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    36
 * Contributor(s):
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    37
 *   Dr Vipul Gupta <vipul.gupta@sun.com> and
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    38
 *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    39
 *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    40
 * Alternatively, the contents of this file may be used under the terms of
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    41
 * either the GNU General Public License Version 2 or later (the "GPL"), or
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    42
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    43
 * in which case the provisions of the GPL or the LGPL are applicable instead
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    44
 * of those above. If you wish to allow use of your version of this file only
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    45
 * under the terms of either the GPL or the LGPL, and not to allow others to
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    46
 * use your version of this file under the terms of the MPL, indicate your
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    47
 * decision by deleting the provisions above and replace them with the notice
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    48
 * and other provisions required by the GPL or the LGPL. If you do not delete
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    49
 * the provisions above, a recipient may use your version of this file under
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    50
 * the terms of any one of the MPL, the GPL or the LGPL.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    51
 *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    52
 *********************************************************************** */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    53
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    54
 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    55
 * Use is subject to license terms.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    56
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    57
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    58
#pragma ident   "%Z%%M% %I%     %E% SMI"
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    59
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    60
#include "mplogic.h"
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    61
#include "ec.h"
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    62
#include "ecl.h"
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    63
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    64
#include <sys/types.h>
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    65
#ifndef _KERNEL
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    66
#include <stdlib.h>
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    67
#include <string.h>
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    68
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    69
#ifndef _WIN32
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    70
#include <strings.h>
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    71
#endif /* _WIN32 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    72
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    73
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    74
#include "ecl-exp.h"
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    75
#include "mpi.h"
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    76
#include "ecc_impl.h"
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    77
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    78
#ifdef _KERNEL
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    79
#define PORT_ZFree(p, l)                bzero((p), (l)); kmem_free((p), (l))
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    80
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    81
#ifndef _WIN32
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    82
#define PORT_ZFree(p, l)                bzero((p), (l)); free((p))
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    83
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    84
#define PORT_ZFree(p, l)                memset((p), 0, (l)); free((p))
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    85
#endif /* _WIN32 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    86
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    87
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    88
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    89
 * Returns true if pointP is the point at infinity, false otherwise
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    90
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    91
PRBool
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    92
ec_point_at_infinity(SECItem *pointP)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    93
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    94
    unsigned int i;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    95
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    96
    for (i = 1; i < pointP->len; i++) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    97
        if (pointP->data[i] != 0x00) return PR_FALSE;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    98
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    99
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   100
    return PR_TRUE;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   101
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   102
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   103
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   104
 * Computes scalar point multiplication pointQ = k1 * G + k2 * pointP for
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   105
 * the curve whose parameters are encoded in params with base point G.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   106
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   107
SECStatus
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   108
ec_points_mul(const ECParams *params, const mp_int *k1, const mp_int *k2,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   109
             const SECItem *pointP, SECItem *pointQ, int kmflag)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   110
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   111
    mp_int Px, Py, Qx, Qy;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   112
    mp_int Gx, Gy, order, irreducible, a, b;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   113
#if 0 /* currently don't support non-named curves */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   114
    unsigned int irr_arr[5];
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   115
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   116
    ECGroup *group = NULL;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   117
    SECStatus rv = SECFailure;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   118
    mp_err err = MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   119
    int len;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   120
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   121
#if EC_DEBUG
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   122
    int i;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   123
    char mpstr[256];
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   124
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   125
    printf("ec_points_mul: params [len=%d]:", params->DEREncoding.len);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   126
    for (i = 0; i < params->DEREncoding.len; i++)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   127
            printf("%02x:", params->DEREncoding.data[i]);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   128
    printf("\n");
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   129
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   130
        if (k1 != NULL) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   131
                mp_tohex(k1, mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   132
                printf("ec_points_mul: scalar k1: %s\n", mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   133
                mp_todecimal(k1, mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   134
                printf("ec_points_mul: scalar k1: %s (dec)\n", mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   135
        }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   136
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   137
        if (k2 != NULL) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   138
                mp_tohex(k2, mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   139
                printf("ec_points_mul: scalar k2: %s\n", mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   140
                mp_todecimal(k2, mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   141
                printf("ec_points_mul: scalar k2: %s (dec)\n", mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   142
        }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   143
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   144
        if (pointP != NULL) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   145
                printf("ec_points_mul: pointP [len=%d]:", pointP->len);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   146
                for (i = 0; i < pointP->len; i++)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   147
                        printf("%02x:", pointP->data[i]);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   148
                printf("\n");
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   149
        }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   150
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   151
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   152
        /* NOTE: We only support uncompressed points for now */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   153
        len = (params->fieldID.size + 7) >> 3;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   154
        if (pointP != NULL) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   155
                if ((pointP->data[0] != EC_POINT_FORM_UNCOMPRESSED) ||
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   156
                        (pointP->len != (2 * len + 1))) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   157
                        return SECFailure;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   158
                };
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   159
        }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   160
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   161
        MP_DIGITS(&Px) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   162
        MP_DIGITS(&Py) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   163
        MP_DIGITS(&Qx) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   164
        MP_DIGITS(&Qy) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   165
        MP_DIGITS(&Gx) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   166
        MP_DIGITS(&Gy) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   167
        MP_DIGITS(&order) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   168
        MP_DIGITS(&irreducible) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   169
        MP_DIGITS(&a) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   170
        MP_DIGITS(&b) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   171
        CHECK_MPI_OK( mp_init(&Px, kmflag) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   172
        CHECK_MPI_OK( mp_init(&Py, kmflag) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   173
        CHECK_MPI_OK( mp_init(&Qx, kmflag) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   174
        CHECK_MPI_OK( mp_init(&Qy, kmflag) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   175
        CHECK_MPI_OK( mp_init(&Gx, kmflag) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   176
        CHECK_MPI_OK( mp_init(&Gy, kmflag) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   177
        CHECK_MPI_OK( mp_init(&order, kmflag) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   178
        CHECK_MPI_OK( mp_init(&irreducible, kmflag) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   179
        CHECK_MPI_OK( mp_init(&a, kmflag) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   180
        CHECK_MPI_OK( mp_init(&b, kmflag) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   181
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   182
        if ((k2 != NULL) && (pointP != NULL)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   183
                /* Initialize Px and Py */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   184
                CHECK_MPI_OK( mp_read_unsigned_octets(&Px, pointP->data + 1, (mp_size) len) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   185
                CHECK_MPI_OK( mp_read_unsigned_octets(&Py, pointP->data + 1 + len, (mp_size) len) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   186
        }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   187
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   188
        /* construct from named params, if possible */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   189
        if (params->name != ECCurve_noName) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   190
                group = ECGroup_fromName(params->name, kmflag);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   191
        }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   192
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   193
#if 0 /* currently don't support non-named curves */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   194
        if (group == NULL) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   195
                /* Set up mp_ints containing the curve coefficients */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   196
                CHECK_MPI_OK( mp_read_unsigned_octets(&Gx, params->base.data + 1,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   197
                                                                                  (mp_size) len) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   198
                CHECK_MPI_OK( mp_read_unsigned_octets(&Gy, params->base.data + 1 + len,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   199
                                                                                  (mp_size) len) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   200
                SECITEM_TO_MPINT( params->order, &order );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   201
                SECITEM_TO_MPINT( params->curve.a, &a );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   202
                SECITEM_TO_MPINT( params->curve.b, &b );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   203
                if (params->fieldID.type == ec_field_GFp) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   204
                        SECITEM_TO_MPINT( params->fieldID.u.prime, &irreducible );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   205
                        group = ECGroup_consGFp(&irreducible, &a, &b, &Gx, &Gy, &order, params->cofactor);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   206
                } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   207
                        SECITEM_TO_MPINT( params->fieldID.u.poly, &irreducible );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   208
                        irr_arr[0] = params->fieldID.size;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   209
                        irr_arr[1] = params->fieldID.k1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   210
                        irr_arr[2] = params->fieldID.k2;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   211
                        irr_arr[3] = params->fieldID.k3;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   212
                        irr_arr[4] = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   213
                        group = ECGroup_consGF2m(&irreducible, irr_arr, &a, &b, &Gx, &Gy, &order, params->cofactor);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   214
                }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   215
        }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   216
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   217
        if (group == NULL)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   218
                goto cleanup;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   219
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   220
        if ((k2 != NULL) && (pointP != NULL)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   221
                CHECK_MPI_OK( ECPoints_mul(group, k1, k2, &Px, &Py, &Qx, &Qy) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   222
        } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   223
                CHECK_MPI_OK( ECPoints_mul(group, k1, NULL, NULL, NULL, &Qx, &Qy) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   224
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   225
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   226
    /* Construct the SECItem representation of point Q */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   227
    pointQ->data[0] = EC_POINT_FORM_UNCOMPRESSED;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   228
    CHECK_MPI_OK( mp_to_fixlen_octets(&Qx, pointQ->data + 1,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   229
                                      (mp_size) len) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   230
    CHECK_MPI_OK( mp_to_fixlen_octets(&Qy, pointQ->data + 1 + len,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   231
                                      (mp_size) len) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   232
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   233
    rv = SECSuccess;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   234
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   235
#if EC_DEBUG
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   236
    printf("ec_points_mul: pointQ [len=%d]:", pointQ->len);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   237
    for (i = 0; i < pointQ->len; i++)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   238
            printf("%02x:", pointQ->data[i]);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   239
    printf("\n");
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   240
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   241
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   242
cleanup:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   243
    ECGroup_free(group);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   244
    mp_clear(&Px);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   245
    mp_clear(&Py);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   246
    mp_clear(&Qx);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   247
    mp_clear(&Qy);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   248
    mp_clear(&Gx);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   249
    mp_clear(&Gy);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   250
    mp_clear(&order);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   251
    mp_clear(&irreducible);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   252
    mp_clear(&a);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   253
    mp_clear(&b);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   254
    if (err) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   255
        MP_TO_SEC_ERROR(err);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   256
        rv = SECFailure;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   257
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   258
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   259
    return rv;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   260
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   261
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   262
/* Generates a new EC key pair. The private key is a supplied
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   263
 * value and the public key is the result of performing a scalar
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   264
 * point multiplication of that value with the curve's base point.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   265
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   266
SECStatus
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   267
ec_NewKey(ECParams *ecParams, ECPrivateKey **privKey,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   268
    const unsigned char *privKeyBytes, int privKeyLen, int kmflag)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   269
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   270
    SECStatus rv = SECFailure;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   271
    PRArenaPool *arena;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   272
    ECPrivateKey *key;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   273
    mp_int k;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   274
    mp_err err = MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   275
    int len;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   276
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   277
#if EC_DEBUG
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   278
    printf("ec_NewKey called\n");
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   279
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   280
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   281
#ifndef _WIN32
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   282
int printf();
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   283
#endif /* _WIN32 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   284
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   285
    if (!ecParams || !privKey || !privKeyBytes || (privKeyLen < 0)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   286
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   287
        return SECFailure;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   288
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   289
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   290
    /* Initialize an arena for the EC key. */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   291
    if (!(arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE)))
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   292
        return SECFailure;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   293
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   294
    key = (ECPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(ECPrivateKey),
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   295
        kmflag);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   296
    if (!key) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   297
        PORT_FreeArena(arena, PR_TRUE);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   298
        return SECFailure;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   299
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   300
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   301
    /* Set the version number (SEC 1 section C.4 says it should be 1) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   302
    SECITEM_AllocItem(arena, &key->version, 1, kmflag);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   303
    key->version.data[0] = 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   304
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   305
    /* Copy all of the fields from the ECParams argument to the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   306
     * ECParams structure within the private key.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   307
     */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   308
    key->ecParams.arena = arena;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   309
    key->ecParams.type = ecParams->type;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   310
    key->ecParams.fieldID.size = ecParams->fieldID.size;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   311
    key->ecParams.fieldID.type = ecParams->fieldID.type;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   312
    if (ecParams->fieldID.type == ec_field_GFp) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   313
        CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.fieldID.u.prime,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   314
            &ecParams->fieldID.u.prime, kmflag));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   315
    } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   316
        CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.fieldID.u.poly,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   317
            &ecParams->fieldID.u.poly, kmflag));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   318
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   319
    key->ecParams.fieldID.k1 = ecParams->fieldID.k1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   320
    key->ecParams.fieldID.k2 = ecParams->fieldID.k2;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   321
    key->ecParams.fieldID.k3 = ecParams->fieldID.k3;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   322
    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curve.a,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   323
        &ecParams->curve.a, kmflag));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   324
    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curve.b,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   325
        &ecParams->curve.b, kmflag));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   326
    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curve.seed,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   327
        &ecParams->curve.seed, kmflag));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   328
    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.base,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   329
        &ecParams->base, kmflag));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   330
    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.order,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   331
        &ecParams->order, kmflag));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   332
    key->ecParams.cofactor = ecParams->cofactor;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   333
    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.DEREncoding,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   334
        &ecParams->DEREncoding, kmflag));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   335
    key->ecParams.name = ecParams->name;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   336
    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curveOID,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   337
        &ecParams->curveOID, kmflag));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   338
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   339
    len = (ecParams->fieldID.size + 7) >> 3;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   340
    SECITEM_AllocItem(arena, &key->publicValue, 2*len + 1, kmflag);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   341
    len = ecParams->order.len;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   342
    SECITEM_AllocItem(arena, &key->privateValue, len, kmflag);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   343
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   344
    /* Copy private key */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   345
    if (privKeyLen >= len) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   346
        memcpy(key->privateValue.data, privKeyBytes, len);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   347
    } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   348
        memset(key->privateValue.data, 0, (len - privKeyLen));
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   349
        memcpy(key->privateValue.data + (len - privKeyLen), privKeyBytes, privKeyLen);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   350
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   351
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   352
    /* Compute corresponding public key */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   353
    MP_DIGITS(&k) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   354
    CHECK_MPI_OK( mp_init(&k, kmflag) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   355
    CHECK_MPI_OK( mp_read_unsigned_octets(&k, key->privateValue.data,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   356
        (mp_size) len) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   357
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   358
    rv = ec_points_mul(ecParams, &k, NULL, NULL, &(key->publicValue), kmflag);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   359
    if (rv != SECSuccess) goto cleanup;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   360
    *privKey = key;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   361
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   362
cleanup:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   363
    mp_clear(&k);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   364
    if (rv)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   365
        PORT_FreeArena(arena, PR_TRUE);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   366
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   367
#if EC_DEBUG
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   368
    printf("ec_NewKey returning %s\n",
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   369
        (rv == SECSuccess) ? "success" : "failure");
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   370
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   371
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   372
    return rv;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   373
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   374
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   375
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   376
/* Generates a new EC key pair. The private key is a supplied
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   377
 * random value (in seed) and the public key is the result of
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   378
 * performing a scalar point multiplication of that value with
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   379
 * the curve's base point.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   380
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   381
SECStatus
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   382
EC_NewKeyFromSeed(ECParams *ecParams, ECPrivateKey **privKey,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   383
    const unsigned char *seed, int seedlen, int kmflag)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   384
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   385
    SECStatus rv = SECFailure;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   386
    rv = ec_NewKey(ecParams, privKey, seed, seedlen, kmflag);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   387
    return rv;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   388
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   389
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   390
/* Generate a random private key using the algorithm A.4.1 of ANSI X9.62,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   391
 * modified a la FIPS 186-2 Change Notice 1 to eliminate the bias in the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   392
 * random number generator.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   393
 *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   394
 * Parameters
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   395
 * - order: a buffer that holds the curve's group order
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   396
 * - len: the length in octets of the order buffer
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   397
 * - random: a buffer of 2 * len random bytes
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   398
 * - randomlen: the length in octets of the random buffer
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   399
 *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   400
 * Return Value
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   401
 * Returns a buffer of len octets that holds the private key. The caller
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   402
 * is responsible for freeing the buffer with PORT_ZFree.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   403
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   404
static unsigned char *
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   405
ec_GenerateRandomPrivateKey(const unsigned char *order, int len,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   406
    const unsigned char *random, int randomlen, int kmflag)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   407
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   408
    SECStatus rv = SECSuccess;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   409
    mp_err err;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   410
    unsigned char *privKeyBytes = NULL;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   411
    mp_int privKeyVal, order_1, one;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   412
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   413
    MP_DIGITS(&privKeyVal) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   414
    MP_DIGITS(&order_1) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   415
    MP_DIGITS(&one) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   416
    CHECK_MPI_OK( mp_init(&privKeyVal, kmflag) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   417
    CHECK_MPI_OK( mp_init(&order_1, kmflag) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   418
    CHECK_MPI_OK( mp_init(&one, kmflag) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   419
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   420
    /*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   421
     * Reduces the 2*len buffer of random bytes modulo the group order.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   422
     */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   423
    if ((privKeyBytes = PORT_Alloc(2*len, kmflag)) == NULL) goto cleanup;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   424
    if (randomlen != 2 * len) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   425
        goto cleanup;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   426
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   427
    /* No need to generate - random bytes are now supplied */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   428
    /* CHECK_SEC_OK( RNG_GenerateGlobalRandomBytes(privKeyBytes, 2*len) );*/
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   429
    memcpy(privKeyBytes, random, randomlen);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   430
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   431
    CHECK_MPI_OK( mp_read_unsigned_octets(&privKeyVal, privKeyBytes, 2*len) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   432
    CHECK_MPI_OK( mp_read_unsigned_octets(&order_1, order, len) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   433
    CHECK_MPI_OK( mp_set_int(&one, 1) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   434
    CHECK_MPI_OK( mp_sub(&order_1, &one, &order_1) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   435
    CHECK_MPI_OK( mp_mod(&privKeyVal, &order_1, &privKeyVal) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   436
    CHECK_MPI_OK( mp_add(&privKeyVal, &one, &privKeyVal) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   437
    CHECK_MPI_OK( mp_to_fixlen_octets(&privKeyVal, privKeyBytes, len) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   438
    memset(privKeyBytes+len, 0, len);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   439
cleanup:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   440
    mp_clear(&privKeyVal);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   441
    mp_clear(&order_1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   442
    mp_clear(&one);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   443
    if (err < MP_OKAY) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   444
        MP_TO_SEC_ERROR(err);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   445
        rv = SECFailure;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   446
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   447
    if (rv != SECSuccess && privKeyBytes) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   448
#ifdef _KERNEL
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   449
        kmem_free(privKeyBytes, 2*len);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   450
#else
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   451
        free(privKeyBytes);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   452
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   453
        privKeyBytes = NULL;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   454
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   455
    return privKeyBytes;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   456
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   457
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   458
/* Generates a new EC key pair. The private key is a random value and
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   459
 * the public key is the result of performing a scalar point multiplication
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   460
 * of that value with the curve's base point.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   461
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   462
SECStatus
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   463
EC_NewKey(ECParams *ecParams, ECPrivateKey **privKey,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   464
    const unsigned char* random, int randomlen, int kmflag)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   465
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   466
    SECStatus rv = SECFailure;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   467
    int len;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   468
    unsigned char *privKeyBytes = NULL;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   469
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   470
    if (!ecParams) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   471
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   472
        return SECFailure;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   473
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   474
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   475
    len = ecParams->order.len;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   476
    privKeyBytes = ec_GenerateRandomPrivateKey(ecParams->order.data, len,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   477
        random, randomlen, kmflag);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   478
    if (privKeyBytes == NULL) goto cleanup;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   479
    /* generate public key */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   480
    CHECK_SEC_OK( ec_NewKey(ecParams, privKey, privKeyBytes, len, kmflag) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   481
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   482
cleanup:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   483
    if (privKeyBytes) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   484
        PORT_ZFree(privKeyBytes, len * 2);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   485
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   486
#if EC_DEBUG
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   487
    printf("EC_NewKey returning %s\n",
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   488
        (rv == SECSuccess) ? "success" : "failure");
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   489
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   490
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   491
    return rv;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   492
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   493
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   494
/* Validates an EC public key as described in Section 5.2.2 of
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   495
 * X9.62. The ECDH primitive when used without the cofactor does
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   496
 * not address small subgroup attacks, which may occur when the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   497
 * public key is not valid. These attacks can be prevented by
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   498
 * validating the public key before using ECDH.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   499
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   500
SECStatus
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   501
EC_ValidatePublicKey(ECParams *ecParams, SECItem *publicValue, int kmflag)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   502
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   503
    mp_int Px, Py;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   504
    ECGroup *group = NULL;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   505
    SECStatus rv = SECFailure;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   506
    mp_err err = MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   507
    int len;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   508
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   509
    if (!ecParams || !publicValue) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   510
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   511
        return SECFailure;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   512
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   513
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   514
    /* NOTE: We only support uncompressed points for now */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   515
    len = (ecParams->fieldID.size + 7) >> 3;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   516
    if (publicValue->data[0] != EC_POINT_FORM_UNCOMPRESSED) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   517
        PORT_SetError(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   518
        return SECFailure;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   519
    } else if (publicValue->len != (2 * len + 1)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   520
        PORT_SetError(SEC_ERROR_BAD_KEY);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   521
        return SECFailure;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   522
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   523
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   524
    MP_DIGITS(&Px) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   525
    MP_DIGITS(&Py) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   526
    CHECK_MPI_OK( mp_init(&Px, kmflag) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   527
    CHECK_MPI_OK( mp_init(&Py, kmflag) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   528
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   529
    /* Initialize Px and Py */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   530
    CHECK_MPI_OK( mp_read_unsigned_octets(&Px, publicValue->data + 1, (mp_size) len) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   531
    CHECK_MPI_OK( mp_read_unsigned_octets(&Py, publicValue->data + 1 + len, (mp_size) len) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   532
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   533
    /* construct from named params */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   534
    group = ECGroup_fromName(ecParams->name, kmflag);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   535
    if (group == NULL) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   536
        /*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   537
         * ECGroup_fromName fails if ecParams->name is not a valid
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   538
         * ECCurveName value, or if we run out of memory, or perhaps
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   539
         * for other reasons.  Unfortunately if ecParams->name is a
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   540
         * valid ECCurveName value, we don't know what the right error
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   541
         * code should be because ECGroup_fromName doesn't return an
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   542
         * error code to the caller.  Set err to MP_UNDEF because
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   543
         * that's what ECGroup_fromName uses internally.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   544
         */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   545
        if ((ecParams->name <= ECCurve_noName) ||
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   546
            (ecParams->name >= ECCurve_pastLastCurve)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   547
            err = MP_BADARG;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   548
        } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   549
            err = MP_UNDEF;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   550
        }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   551
        goto cleanup;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   552
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   553
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   554
    /* validate public point */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   555
    if ((err = ECPoint_validate(group, &Px, &Py)) < MP_YES) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   556
        if (err == MP_NO) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   557
            PORT_SetError(SEC_ERROR_BAD_KEY);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   558
            rv = SECFailure;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   559
            err = MP_OKAY;  /* don't change the error code */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   560
        }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   561
        goto cleanup;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   562
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   563
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   564
    rv = SECSuccess;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   565
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   566
cleanup:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   567
    ECGroup_free(group);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   568
    mp_clear(&Px);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   569
    mp_clear(&Py);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   570
    if (err) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   571
        MP_TO_SEC_ERROR(err);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   572
        rv = SECFailure;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   573
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   574
    return rv;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   575
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   576
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   577
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   578
** Performs an ECDH key derivation by computing the scalar point
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   579
** multiplication of privateValue and publicValue (with or without the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   580
** cofactor) and returns the x-coordinate of the resulting elliptic
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   581
** curve point in derived secret.  If successful, derivedSecret->data
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   582
** is set to the address of the newly allocated buffer containing the
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   583
** derived secret, and derivedSecret->len is the size of the secret
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   584
** produced. It is the caller's responsibility to free the allocated
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   585
** buffer containing the derived secret.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   586
*/
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   587
SECStatus
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   588
ECDH_Derive(SECItem  *publicValue,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   589
            ECParams *ecParams,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   590
            SECItem  *privateValue,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   591
            PRBool    withCofactor,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   592
            SECItem  *derivedSecret,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   593
            int kmflag)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   594
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   595
    SECStatus rv = SECFailure;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   596
    unsigned int len = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   597
    SECItem pointQ = {siBuffer, NULL, 0};
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   598
    mp_int k; /* to hold the private value */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   599
    mp_int cofactor;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   600
    mp_err err = MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   601
#if EC_DEBUG
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   602
    int i;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   603
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   604
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   605
    if (!publicValue || !ecParams || !privateValue ||
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   606
        !derivedSecret) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   607
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   608
        return SECFailure;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   609
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   610
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   611
    memset(derivedSecret, 0, sizeof *derivedSecret);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   612
    len = (ecParams->fieldID.size + 7) >> 3;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   613
    pointQ.len = 2*len + 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   614
    if ((pointQ.data = PORT_Alloc(2*len + 1, kmflag)) == NULL) goto cleanup;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   615
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   616
    MP_DIGITS(&k) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   617
    CHECK_MPI_OK( mp_init(&k, kmflag) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   618
    CHECK_MPI_OK( mp_read_unsigned_octets(&k, privateValue->data,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   619
                                          (mp_size) privateValue->len) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   620
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   621
    if (withCofactor && (ecParams->cofactor != 1)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   622
            /* multiply k with the cofactor */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   623
            MP_DIGITS(&cofactor) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   624
            CHECK_MPI_OK( mp_init(&cofactor, kmflag) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   625
            mp_set(&cofactor, ecParams->cofactor);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   626
            CHECK_MPI_OK( mp_mul(&k, &cofactor, &k) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   627
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   628
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   629
    /* Multiply our private key and peer's public point */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   630
    if ((ec_points_mul(ecParams, NULL, &k, publicValue, &pointQ, kmflag) != SECSuccess) ||
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   631
        ec_point_at_infinity(&pointQ))
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   632
        goto cleanup;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   633
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   634
    /* Allocate memory for the derived secret and copy
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   635
     * the x co-ordinate of pointQ into it.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   636
     */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   637
    SECITEM_AllocItem(NULL, derivedSecret, len, kmflag);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   638
    memcpy(derivedSecret->data, pointQ.data + 1, len);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   639
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   640
    rv = SECSuccess;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   641
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   642
#if EC_DEBUG
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   643
    printf("derived_secret:\n");
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   644
    for (i = 0; i < derivedSecret->len; i++)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   645
        printf("%02x:", derivedSecret->data[i]);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   646
    printf("\n");
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   647
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   648
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   649
cleanup:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   650
    mp_clear(&k);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   651
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   652
    if (pointQ.data) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   653
        PORT_ZFree(pointQ.data, 2*len + 1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   654
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   655
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   656
    return rv;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   657
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   658
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   659
/* Computes the ECDSA signature (a concatenation of two values r and s)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   660
 * on the digest using the given key and the random value kb (used in
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   661
 * computing s).
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   662
 */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   663
SECStatus
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   664
ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   665
    const SECItem *digest, const unsigned char *kb, const int kblen, int kmflag)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   666
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   667
    SECStatus rv = SECFailure;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   668
    mp_int x1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   669
    mp_int d, k;     /* private key, random integer */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   670
    mp_int r, s;     /* tuple (r, s) is the signature */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   671
    mp_int n;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   672
    mp_err err = MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   673
    ECParams *ecParams = NULL;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   674
    SECItem kGpoint = { siBuffer, NULL, 0};
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   675
    int flen = 0;    /* length in bytes of the field size */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   676
    unsigned olen;   /* length in bytes of the base point order */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   677
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   678
#if EC_DEBUG
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   679
    char mpstr[256];
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   680
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   681
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   682
    /* Initialize MPI integers. */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   683
    /* must happen before the first potential call to cleanup */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   684
    MP_DIGITS(&x1) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   685
    MP_DIGITS(&d) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   686
    MP_DIGITS(&k) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   687
    MP_DIGITS(&r) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   688
    MP_DIGITS(&s) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   689
    MP_DIGITS(&n) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   690
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   691
    /* Check args */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   692
    if (!key || !signature || !digest || !kb || (kblen < 0)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   693
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   694
        goto cleanup;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   695
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   696
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   697
    ecParams = &(key->ecParams);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   698
    flen = (ecParams->fieldID.size + 7) >> 3;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   699
    olen = ecParams->order.len;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   700
    if (signature->data == NULL) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   701
        /* a call to get the signature length only */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   702
        goto finish;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   703
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   704
    if (signature->len < 2*olen) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   705
        PORT_SetError(SEC_ERROR_OUTPUT_LEN);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   706
        rv = SECBufferTooSmall;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   707
        goto cleanup;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   708
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   709
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   710
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   711
    CHECK_MPI_OK( mp_init(&x1, kmflag) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   712
    CHECK_MPI_OK( mp_init(&d, kmflag) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   713
    CHECK_MPI_OK( mp_init(&k, kmflag) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   714
    CHECK_MPI_OK( mp_init(&r, kmflag) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   715
    CHECK_MPI_OK( mp_init(&s, kmflag) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   716
    CHECK_MPI_OK( mp_init(&n, kmflag) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   717
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   718
    SECITEM_TO_MPINT( ecParams->order, &n );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   719
    SECITEM_TO_MPINT( key->privateValue, &d );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   720
    CHECK_MPI_OK( mp_read_unsigned_octets(&k, kb, kblen) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   721
    /* Make sure k is in the interval [1, n-1] */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   722
    if ((mp_cmp_z(&k) <= 0) || (mp_cmp(&k, &n) >= 0)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   723
#if EC_DEBUG
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   724
        printf("k is outside [1, n-1]\n");
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   725
        mp_tohex(&k, mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   726
        printf("k : %s \n", mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   727
        mp_tohex(&n, mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   728
        printf("n : %s \n", mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   729
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   730
        PORT_SetError(SEC_ERROR_NEED_RANDOM);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   731
        goto cleanup;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   732
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   733
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   734
    /*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   735
    ** ANSI X9.62, Section 5.3.2, Step 2
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   736
    **
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   737
    ** Compute kG
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   738
    */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   739
    kGpoint.len = 2*flen + 1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   740
    kGpoint.data = PORT_Alloc(2*flen + 1, kmflag);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   741
    if ((kGpoint.data == NULL) ||
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   742
        (ec_points_mul(ecParams, &k, NULL, NULL, &kGpoint, kmflag)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   743
            != SECSuccess))
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   744
        goto cleanup;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   745
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   746
    /*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   747
    ** ANSI X9.62, Section 5.3.3, Step 1
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   748
    **
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   749
    ** Extract the x co-ordinate of kG into x1
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   750
    */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   751
    CHECK_MPI_OK( mp_read_unsigned_octets(&x1, kGpoint.data + 1,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   752
                                          (mp_size) flen) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   753
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   754
    /*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   755
    ** ANSI X9.62, Section 5.3.3, Step 2
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   756
    **
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   757
    ** r = x1 mod n  NOTE: n is the order of the curve
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   758
    */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   759
    CHECK_MPI_OK( mp_mod(&x1, &n, &r) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   760
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   761
    /*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   762
    ** ANSI X9.62, Section 5.3.3, Step 3
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   763
    **
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   764
    ** verify r != 0
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   765
    */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   766
    if (mp_cmp_z(&r) == 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   767
        PORT_SetError(SEC_ERROR_NEED_RANDOM);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   768
        goto cleanup;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   769
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   770
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   771
    /*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   772
    ** ANSI X9.62, Section 5.3.3, Step 4
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   773
    **
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   774
    ** s = (k**-1 * (HASH(M) + d*r)) mod n
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   775
    */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   776
    SECITEM_TO_MPINT(*digest, &s);        /* s = HASH(M)     */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   777
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   778
    /* In the definition of EC signing, digests are truncated
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   779
     * to the length of n in bits.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   780
     * (see SEC 1 "Elliptic Curve Digit Signature Algorithm" section 4.1.*/
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   781
    if (digest->len*8 > ecParams->fieldID.size) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   782
        mpl_rsh(&s,&s,digest->len*8 - ecParams->fieldID.size);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   783
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   784
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   785
#if EC_DEBUG
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   786
    mp_todecimal(&n, mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   787
    printf("n : %s (dec)\n", mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   788
    mp_todecimal(&d, mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   789
    printf("d : %s (dec)\n", mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   790
    mp_tohex(&x1, mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   791
    printf("x1: %s\n", mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   792
    mp_todecimal(&s, mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   793
    printf("digest: %s (decimal)\n", mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   794
    mp_todecimal(&r, mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   795
    printf("r : %s (dec)\n", mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   796
    mp_tohex(&r, mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   797
    printf("r : %s\n", mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   798
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   799
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   800
    CHECK_MPI_OK( mp_invmod(&k, &n, &k) );      /* k = k**-1 mod n */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   801
    CHECK_MPI_OK( mp_mulmod(&d, &r, &n, &d) );  /* d = d * r mod n */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   802
    CHECK_MPI_OK( mp_addmod(&s, &d, &n, &s) );  /* s = s + d mod n */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   803
    CHECK_MPI_OK( mp_mulmod(&s, &k, &n, &s) );  /* s = s * k mod n */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   804
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   805
#if EC_DEBUG
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   806
    mp_todecimal(&s, mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   807
    printf("s : %s (dec)\n", mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   808
    mp_tohex(&s, mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   809
    printf("s : %s\n", mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   810
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   811
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   812
    /*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   813
    ** ANSI X9.62, Section 5.3.3, Step 5
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   814
    **
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   815
    ** verify s != 0
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   816
    */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   817
    if (mp_cmp_z(&s) == 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   818
        PORT_SetError(SEC_ERROR_NEED_RANDOM);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   819
        goto cleanup;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   820
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   821
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   822
   /*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   823
    **
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   824
    ** Signature is tuple (r, s)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   825
    */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   826
    CHECK_MPI_OK( mp_to_fixlen_octets(&r, signature->data, olen) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   827
    CHECK_MPI_OK( mp_to_fixlen_octets(&s, signature->data + olen, olen) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   828
finish:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   829
    signature->len = 2*olen;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   830
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   831
    rv = SECSuccess;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   832
    err = MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   833
cleanup:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   834
    mp_clear(&x1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   835
    mp_clear(&d);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   836
    mp_clear(&k);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   837
    mp_clear(&r);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   838
    mp_clear(&s);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   839
    mp_clear(&n);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   840
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   841
    if (kGpoint.data) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   842
        PORT_ZFree(kGpoint.data, 2*flen + 1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   843
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   844
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   845
    if (err) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   846
        MP_TO_SEC_ERROR(err);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   847
        rv = SECFailure;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   848
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   849
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   850
#if EC_DEBUG
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   851
    printf("ECDSA signing with seed %s\n",
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   852
        (rv == SECSuccess) ? "succeeded" : "failed");
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   853
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   854
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   855
   return rv;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   856
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   857
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   858
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   859
** Computes the ECDSA signature on the digest using the given key
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   860
** and a random seed.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   861
*/
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   862
SECStatus
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   863
ECDSA_SignDigest(ECPrivateKey *key, SECItem *signature, const SECItem *digest,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   864
    const unsigned char* random, int randomLen, int kmflag)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   865
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   866
    SECStatus rv = SECFailure;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   867
    int len;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   868
    unsigned char *kBytes= NULL;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   869
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   870
    if (!key) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   871
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   872
        return SECFailure;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   873
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   874
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   875
    /* Generate random value k */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   876
    len = key->ecParams.order.len;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   877
    kBytes = ec_GenerateRandomPrivateKey(key->ecParams.order.data, len,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   878
        random, randomLen, kmflag);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   879
    if (kBytes == NULL) goto cleanup;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   880
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   881
    /* Generate ECDSA signature with the specified k value */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   882
    rv = ECDSA_SignDigestWithSeed(key, signature, digest, kBytes, len, kmflag);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   883
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   884
cleanup:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   885
    if (kBytes) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   886
        PORT_ZFree(kBytes, len * 2);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   887
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   888
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   889
#if EC_DEBUG
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   890
    printf("ECDSA signing %s\n",
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   891
        (rv == SECSuccess) ? "succeeded" : "failed");
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   892
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   893
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   894
    return rv;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   895
}
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   896
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   897
/*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   898
** Checks the signature on the given digest using the key provided.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   899
*/
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   900
SECStatus
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   901
ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature,
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   902
                 const SECItem *digest, int kmflag)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   903
{
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   904
    SECStatus rv = SECFailure;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   905
    mp_int r_, s_;           /* tuple (r', s') is received signature) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   906
    mp_int c, u1, u2, v;     /* intermediate values used in verification */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   907
    mp_int x1;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   908
    mp_int n;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   909
    mp_err err = MP_OKAY;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   910
    ECParams *ecParams = NULL;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   911
    SECItem pointC = { siBuffer, NULL, 0 };
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   912
    int slen;       /* length in bytes of a half signature (r or s) */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   913
    int flen;       /* length in bytes of the field size */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   914
    unsigned olen;  /* length in bytes of the base point order */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   915
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   916
#if EC_DEBUG
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   917
    char mpstr[256];
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   918
    printf("ECDSA verification called\n");
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   919
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   920
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   921
    /* Initialize MPI integers. */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   922
    /* must happen before the first potential call to cleanup */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   923
    MP_DIGITS(&r_) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   924
    MP_DIGITS(&s_) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   925
    MP_DIGITS(&c) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   926
    MP_DIGITS(&u1) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   927
    MP_DIGITS(&u2) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   928
    MP_DIGITS(&x1) = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   929
    MP_DIGITS(&v)  = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   930
    MP_DIGITS(&n)  = 0;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   931
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   932
    /* Check args */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   933
    if (!key || !signature || !digest) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   934
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   935
        goto cleanup;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   936
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   937
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   938
    ecParams = &(key->ecParams);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   939
    flen = (ecParams->fieldID.size + 7) >> 3;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   940
    olen = ecParams->order.len;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   941
    if (signature->len == 0 || signature->len%2 != 0 ||
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   942
        signature->len > 2*olen) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   943
        PORT_SetError(SEC_ERROR_INPUT_LEN);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   944
        goto cleanup;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   945
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   946
    slen = signature->len/2;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   947
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   948
    SECITEM_AllocItem(NULL, &pointC, 2*flen + 1, kmflag);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   949
    if (pointC.data == NULL)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   950
        goto cleanup;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   951
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   952
    CHECK_MPI_OK( mp_init(&r_, kmflag) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   953
    CHECK_MPI_OK( mp_init(&s_, kmflag) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   954
    CHECK_MPI_OK( mp_init(&c, kmflag)  );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   955
    CHECK_MPI_OK( mp_init(&u1, kmflag) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   956
    CHECK_MPI_OK( mp_init(&u2, kmflag) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   957
    CHECK_MPI_OK( mp_init(&x1, kmflag)  );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   958
    CHECK_MPI_OK( mp_init(&v, kmflag)  );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   959
    CHECK_MPI_OK( mp_init(&n, kmflag)  );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   960
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   961
    /*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   962
    ** Convert received signature (r', s') into MPI integers.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   963
    */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   964
    CHECK_MPI_OK( mp_read_unsigned_octets(&r_, signature->data, slen) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   965
    CHECK_MPI_OK( mp_read_unsigned_octets(&s_, signature->data + slen, slen) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   966
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   967
    /*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   968
    ** ANSI X9.62, Section 5.4.2, Steps 1 and 2
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   969
    **
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   970
    ** Verify that 0 < r' < n and 0 < s' < n
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   971
    */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   972
    SECITEM_TO_MPINT(ecParams->order, &n);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   973
    if (mp_cmp_z(&r_) <= 0 || mp_cmp_z(&s_) <= 0 ||
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   974
        mp_cmp(&r_, &n) >= 0 || mp_cmp(&s_, &n) >= 0) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   975
        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   976
        goto cleanup; /* will return rv == SECFailure */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   977
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   978
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   979
    /*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   980
    ** ANSI X9.62, Section 5.4.2, Step 3
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   981
    **
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   982
    ** c = (s')**-1 mod n
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   983
    */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   984
    CHECK_MPI_OK( mp_invmod(&s_, &n, &c) );      /* c = (s')**-1 mod n */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   985
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   986
    /*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   987
    ** ANSI X9.62, Section 5.4.2, Step 4
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   988
    **
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   989
    ** u1 = ((HASH(M')) * c) mod n
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   990
    */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   991
    SECITEM_TO_MPINT(*digest, &u1);                  /* u1 = HASH(M)     */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   992
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   993
    /* In the definition of EC signing, digests are truncated
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   994
     * to the length of n in bits.
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   995
     * (see SEC 1 "Elliptic Curve Digit Signature Algorithm" section 4.1.*/
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   996
    if (digest->len*8 > ecParams->fieldID.size) {  /* u1 = HASH(M')     */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   997
        mpl_rsh(&u1,&u1,digest->len*8- ecParams->fieldID.size);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   998
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   999
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1000
#if EC_DEBUG
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1001
    mp_todecimal(&r_, mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1002
    printf("r_: %s (dec)\n", mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1003
    mp_todecimal(&s_, mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1004
    printf("s_: %s (dec)\n", mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1005
    mp_todecimal(&c, mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1006
    printf("c : %s (dec)\n", mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1007
    mp_todecimal(&u1, mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1008
    printf("digest: %s (dec)\n", mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1009
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1010
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1011
    CHECK_MPI_OK( mp_mulmod(&u1, &c, &n, &u1) );  /* u1 = u1 * c mod n */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1012
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1013
    /*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1014
    ** ANSI X9.62, Section 5.4.2, Step 4
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1015
    **
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1016
    ** u2 = ((r') * c) mod n
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1017
    */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1018
    CHECK_MPI_OK( mp_mulmod(&r_, &c, &n, &u2) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1019
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1020
    /*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1021
    ** ANSI X9.62, Section 5.4.3, Step 1
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1022
    **
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1023
    ** Compute u1*G + u2*Q
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1024
    ** Here, A = u1.G     B = u2.Q    and   C = A + B
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1025
    ** If the result, C, is the point at infinity, reject the signature
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1026
    */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1027
    if (ec_points_mul(ecParams, &u1, &u2, &key->publicValue, &pointC, kmflag)
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1028
        != SECSuccess) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1029
        rv = SECFailure;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1030
        goto cleanup;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1031
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1032
    if (ec_point_at_infinity(&pointC)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1033
        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1034
        rv = SECFailure;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1035
        goto cleanup;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1036
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1037
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1038
    CHECK_MPI_OK( mp_read_unsigned_octets(&x1, pointC.data + 1, flen) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1039
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1040
    /*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1041
    ** ANSI X9.62, Section 5.4.4, Step 2
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1042
    **
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1043
    ** v = x1 mod n
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1044
    */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1045
    CHECK_MPI_OK( mp_mod(&x1, &n, &v) );
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1046
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1047
#if EC_DEBUG
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1048
    mp_todecimal(&r_, mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1049
    printf("r_: %s (dec)\n", mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1050
    mp_todecimal(&v, mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1051
    printf("v : %s (dec)\n", mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1052
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1053
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1054
    /*
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1055
    ** ANSI X9.62, Section 5.4.4, Step 3
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1056
    **
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1057
    ** Verification:  v == r'
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1058
    */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1059
    if (mp_cmp(&v, &r_)) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1060
        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1061
        rv = SECFailure; /* Signature failed to verify. */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1062
    } else {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1063
        rv = SECSuccess; /* Signature verified. */
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1064
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1065
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1066
#if EC_DEBUG
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1067
    mp_todecimal(&u1, mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1068
    printf("u1: %s (dec)\n", mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1069
    mp_todecimal(&u2, mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1070
    printf("u2: %s (dec)\n", mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1071
    mp_tohex(&x1, mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1072
    printf("x1: %s\n", mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1073
    mp_todecimal(&v, mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1074
    printf("v : %s (dec)\n", mpstr);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1075
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1076
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1077
cleanup:
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1078
    mp_clear(&r_);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1079
    mp_clear(&s_);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1080
    mp_clear(&c);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1081
    mp_clear(&u1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1082
    mp_clear(&u2);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1083
    mp_clear(&x1);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1084
    mp_clear(&v);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1085
    mp_clear(&n);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1086
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1087
    if (pointC.data) SECITEM_FreeItem(&pointC, PR_FALSE);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1088
    if (err) {
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1089
        MP_TO_SEC_ERROR(err);
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1090
        rv = SECFailure;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1091
    }
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1092
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1093
#if EC_DEBUG
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1094
    printf("ECDSA verification %s\n",
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1095
        (rv == SECSuccess) ? "succeeded" : "failed");
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1096
#endif
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1097
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1098
    return rv;
e549cea58864 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1099
}