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