jdk/src/share/native/sun/security/ec/impl/ec.c
author ohair
Wed, 06 Apr 2011 22:06:11 -0700
changeset 9035 1255eb81cc2f
parent 8175 27e80dc06104
child 9774 50a2b28ca54c
permissions -rw-r--r--
7033660: Update copyright year to 2011 on any files changed in 2011 Reviewed-by: dholmes
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3863
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
     1
/* *********************************************************************
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
     2
 *
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
     3
 * Sun elects to have this file available under and governed by the
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
     4
 * Mozilla Public License Version 1.1 ("MPL") (see
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
     5
 * http://www.mozilla.org/MPL/ for full license text). For the avoidance
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
     6
 * of doubt and subject to the following, Sun also elects to allow
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
     7
 * licensees to use this file under the MPL, the GNU General Public
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
     8
 * License version 2 only or the Lesser General Public License version
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
     9
 * 2.1 only. Any references to the "GNU General Public License version 2
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    10
 * or later" or "GPL" in the following shall be construed to mean the
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    11
 * GNU General Public License version 2 only. Any references to the "GNU
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    12
 * Lesser General Public License version 2.1 or later" or "LGPL" in the
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    13
 * following shall be construed to mean the GNU Lesser General Public
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    14
 * License version 2.1 only. However, the following notice accompanied
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    15
 * the original version of this file:
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    16
 *
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    17
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    18
 *
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    19
 * The contents of this file are subject to the Mozilla Public License Version
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    20
 * 1.1 (the "License"); you may not use this file except in compliance with
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    21
 * the License. You may obtain a copy of the License at
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    22
 * http://www.mozilla.org/MPL/
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    23
 *
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    24
 * Software distributed under the License is distributed on an "AS IS" basis,
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    25
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    26
 * for the specific language governing rights and limitations under the
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    27
 * License.
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    28
 *
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    29
 * 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
    30
 *
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    31
 * 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
    32
 * Sun Microsystems, Inc.
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    33
 * Portions created by the Initial Developer are Copyright (C) 2003
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    34
 * 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
    35
 *
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    36
 * Contributor(s):
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    37
 *   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
    38
 *   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
    39
 *
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    40
 * Alternatively, the contents of this file may be used under the terms of
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    41
 * either the GNU General Public License Version 2 or later (the "GPL"), or
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    42
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    43
 * in which case the provisions of the GPL or the LGPL are applicable instead
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    44
 * of those above. If you wish to allow use of your version of this file only
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    45
 * under the terms of either the GPL or the LGPL, and not to allow others to
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    46
 * use your version of this file under the terms of the MPL, indicate your
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    47
 * decision by deleting the provisions above and replace them with the notice
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    48
 * and other provisions required by the GPL or the LGPL. If you do not delete
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    49
 * the provisions above, a recipient may use your version of this file under
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    50
 * the terms of any one of the MPL, the GPL or the LGPL.
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    51
 *
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    52
 *********************************************************************** */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    53
/*
9035
1255eb81cc2f 7033660: Update copyright year to 2011 on any files changed in 2011
ohair
parents: 8175
diff changeset
    54
 * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
3863
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    55
 * Use is subject to license terms.
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    56
 */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    57
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    58
#include "mplogic.h"
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    59
#include "ec.h"
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    60
#include "ecl.h"
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    61
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    62
#include <sys/types.h>
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    63
#ifndef _KERNEL
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    64
#include <stdlib.h>
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    65
#include <string.h>
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    66
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    67
#ifndef _WIN32
8175
27e80dc06104 6989705: ECC security code native code compiler warnings
vinnie
parents: 5506
diff changeset
    68
#include <stdio.h>
3863
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    69
#include <strings.h>
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    70
#endif /* _WIN32 */
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
#endif
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    73
#include "ecl-exp.h"
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    74
#include "mpi.h"
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    75
#include "ecc_impl.h"
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
#ifdef _KERNEL
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    78
#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
    79
#else
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    80
#ifndef _WIN32
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    81
#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
    82
#else
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    83
#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
    84
#endif /* _WIN32 */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    85
#endif
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    86
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
 * 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
    89
 */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    90
PRBool
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    91
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
    92
{
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    93
    unsigned int i;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    94
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    95
    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
    96
        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
    97
    }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    98
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
    99
    return PR_TRUE;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   100
}
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
/*
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   103
 * 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
   104
 * 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
   105
 */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   106
SECStatus
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   107
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
   108
             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
   109
{
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   110
    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
   111
    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
   112
#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
   113
    unsigned int irr_arr[5];
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   114
#endif
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   115
    ECGroup *group = NULL;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   116
    SECStatus rv = SECFailure;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   117
    mp_err err = MP_OKAY;
8175
27e80dc06104 6989705: ECC security code native code compiler warnings
vinnie
parents: 5506
diff changeset
   118
    unsigned int len;
3863
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   119
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   120
#if EC_DEBUG
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   121
    int i;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   122
    char mpstr[256];
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
    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
   125
    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
   126
            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
   127
    printf("\n");
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   128
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   129
        if (k1 != NULL) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   130
                mp_tohex(k1, mpstr);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   131
                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
   132
                mp_todecimal(k1, mpstr);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   133
                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
   134
        }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   135
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   136
        if (k2 != NULL) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   137
                mp_tohex(k2, mpstr);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   138
                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
   139
                mp_todecimal(k2, mpstr);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   140
                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
   141
        }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   142
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   143
        if (pointP != NULL) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   144
                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
   145
                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
   146
                        printf("%02x:", pointP->data[i]);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   147
                printf("\n");
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   148
        }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   149
#endif
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   150
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   151
        /* 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
   152
        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
   153
        if (pointP != NULL) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   154
                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
   155
                        (pointP->len != (2 * len + 1))) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   156
                        return SECFailure;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   157
                };
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   158
        }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   159
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   160
        MP_DIGITS(&Px) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   161
        MP_DIGITS(&Py) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   162
        MP_DIGITS(&Qx) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   163
        MP_DIGITS(&Qy) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   164
        MP_DIGITS(&Gx) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   165
        MP_DIGITS(&Gy) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   166
        MP_DIGITS(&order) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   167
        MP_DIGITS(&irreducible) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   168
        MP_DIGITS(&a) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   169
        MP_DIGITS(&b) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   170
        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
   171
        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
   172
        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
   173
        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
   174
        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
   175
        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
   176
        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
   177
        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
   178
        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
   179
        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
   180
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   181
        if ((k2 != NULL) && (pointP != NULL)) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   182
                /* Initialize Px and Py */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   183
                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
   184
                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
   185
        }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   186
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   187
        /* 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
   188
        if (params->name != ECCurve_noName) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   189
                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
   190
        }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   191
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   192
#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
   193
        if (group == NULL) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   194
                /* 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
   195
                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
   196
                                                                                  (mp_size) len) );
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   197
                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
   198
                                                                                  (mp_size) len) );
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   199
                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
   200
                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
   201
                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
   202
                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
   203
                        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
   204
                        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
   205
                } else {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   206
                        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
   207
                        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
   208
                        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
   209
                        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
   210
                        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
   211
                        irr_arr[4] = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   212
                        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
   213
                }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   214
        }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   215
#endif
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   216
        if (group == NULL)
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   217
                goto cleanup;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   218
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   219
        if ((k2 != NULL) && (pointP != NULL)) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   220
                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
   221
        } else {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   222
                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
   223
    }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   224
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   225
    /* 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
   226
    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
   227
    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
   228
                                      (mp_size) len) );
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   229
    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
   230
                                      (mp_size) len) );
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   231
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   232
    rv = SECSuccess;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   233
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   234
#if EC_DEBUG
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   235
    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
   236
    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
   237
            printf("%02x:", pointQ->data[i]);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   238
    printf("\n");
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   239
#endif
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   240
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   241
cleanup:
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   242
    ECGroup_free(group);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   243
    mp_clear(&Px);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   244
    mp_clear(&Py);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   245
    mp_clear(&Qx);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   246
    mp_clear(&Qy);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   247
    mp_clear(&Gx);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   248
    mp_clear(&Gy);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   249
    mp_clear(&order);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   250
    mp_clear(&irreducible);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   251
    mp_clear(&a);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   252
    mp_clear(&b);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   253
    if (err) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   254
        MP_TO_SEC_ERROR(err);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   255
        rv = SECFailure;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   256
    }
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
    return rv;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   259
}
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   260
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   261
/* 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
   262
 * 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
   263
 * 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
   264
 */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   265
SECStatus
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   266
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
   267
    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
   268
{
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   269
    SECStatus rv = SECFailure;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   270
    PRArenaPool *arena;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   271
    ECPrivateKey *key;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   272
    mp_int k;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   273
    mp_err err = MP_OKAY;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   274
    int len;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   275
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   276
#if EC_DEBUG
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   277
    printf("ec_NewKey called\n");
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   278
#endif
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   279
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   280
    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
   281
        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
   282
        return SECFailure;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   283
    }
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
    /* 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
   286
    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
   287
        return SECFailure;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   288
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   289
    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
   290
        kmflag);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   291
    if (!key) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   292
        PORT_FreeArena(arena, PR_TRUE);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   293
        return SECFailure;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   294
    }
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
    /* 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
   297
    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
   298
    key->version.data[0] = 1;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   299
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   300
    /* 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
   301
     * 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
   302
     */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   303
    key->ecParams.arena = arena;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   304
    key->ecParams.type = ecParams->type;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   305
    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
   306
    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
   307
    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
   308
        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
   309
            &ecParams->fieldID.u.prime, kmflag));
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   310
    } else {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   311
        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
   312
            &ecParams->fieldID.u.poly, kmflag));
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   313
    }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   314
    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
   315
    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
   316
    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
   317
    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
   318
        &ecParams->curve.a, kmflag));
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   319
    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
   320
        &ecParams->curve.b, kmflag));
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   321
    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
   322
        &ecParams->curve.seed, kmflag));
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   323
    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
   324
        &ecParams->base, kmflag));
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   325
    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
   326
        &ecParams->order, kmflag));
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   327
    key->ecParams.cofactor = ecParams->cofactor;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   328
    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
   329
        &ecParams->DEREncoding, kmflag));
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   330
    key->ecParams.name = ecParams->name;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   331
    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
   332
        &ecParams->curveOID, kmflag));
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   333
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   334
    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
   335
    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
   336
    len = ecParams->order.len;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   337
    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
   338
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   339
    /* Copy private key */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   340
    if (privKeyLen >= len) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   341
        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
   342
    } else {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   343
        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
   344
        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
   345
    }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   346
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   347
    /* Compute corresponding public key */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   348
    MP_DIGITS(&k) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   349
    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
   350
    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
   351
        (mp_size) len) );
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
    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
   354
    if (rv != SECSuccess) goto cleanup;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   355
    *privKey = key;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   356
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   357
cleanup:
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   358
    mp_clear(&k);
8175
27e80dc06104 6989705: ECC security code native code compiler warnings
vinnie
parents: 5506
diff changeset
   359
    if (rv) {
3863
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   360
        PORT_FreeArena(arena, PR_TRUE);
8175
27e80dc06104 6989705: ECC security code native code compiler warnings
vinnie
parents: 5506
diff changeset
   361
    }
3863
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
#if EC_DEBUG
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   364
    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
   365
        (rv == SECSuccess) ? "success" : "failure");
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   366
#endif
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
    return rv;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   369
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   370
}
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
/* 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
   373
 * 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
   374
 * 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
   375
 * the curve's base point.
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   376
 */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   377
SECStatus
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   378
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
   379
    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
   380
{
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   381
    SECStatus rv = SECFailure;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   382
    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
   383
    return rv;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   384
}
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
/* 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
   387
 * 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
   388
 * random number generator.
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   389
 *
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   390
 * Parameters
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   391
 * - 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
   392
 * - 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
   393
 * - 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
   394
 * - 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
   395
 *
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   396
 * Return Value
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   397
 * 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
   398
 * 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
   399
 */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   400
static unsigned char *
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   401
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
   402
    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
   403
{
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   404
    SECStatus rv = SECSuccess;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   405
    mp_err err;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   406
    unsigned char *privKeyBytes = NULL;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   407
    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
   408
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   409
    MP_DIGITS(&privKeyVal) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   410
    MP_DIGITS(&order_1) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   411
    MP_DIGITS(&one) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   412
    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
   413
    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
   414
    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
   415
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   416
    /*
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   417
     * 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
   418
     */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   419
    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
   420
    if (randomlen != 2 * len) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   421
        randomlen = 2 * len;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   422
    }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   423
    /* 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
   424
    /* 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
   425
    memcpy(privKeyBytes, random, randomlen);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   426
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   427
    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
   428
    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
   429
    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
   430
    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
   431
    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
   432
    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
   433
    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
   434
    memset(privKeyBytes+len, 0, len);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   435
cleanup:
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   436
    mp_clear(&privKeyVal);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   437
    mp_clear(&order_1);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   438
    mp_clear(&one);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   439
    if (err < MP_OKAY) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   440
        MP_TO_SEC_ERROR(err);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   441
        rv = SECFailure;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   442
    }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   443
    if (rv != SECSuccess && privKeyBytes) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   444
#ifdef _KERNEL
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   445
        kmem_free(privKeyBytes, 2*len);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   446
#else
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   447
        free(privKeyBytes);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   448
#endif
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   449
        privKeyBytes = NULL;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   450
    }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   451
    return privKeyBytes;
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
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   454
/* 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
   455
 * 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
   456
 * 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
   457
 */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   458
SECStatus
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   459
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
   460
    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
   461
{
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   462
    SECStatus rv = SECFailure;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   463
    int len;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   464
    unsigned char *privKeyBytes = NULL;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   465
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   466
    if (!ecParams) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   467
        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
   468
        return SECFailure;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   469
    }
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
    len = ecParams->order.len;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   472
    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
   473
        random, randomlen, kmflag);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   474
    if (privKeyBytes == NULL) goto cleanup;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   475
    /* generate public key */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   476
    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
   477
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   478
cleanup:
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   479
    if (privKeyBytes) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   480
        PORT_ZFree(privKeyBytes, len * 2);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   481
    }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   482
#if EC_DEBUG
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   483
    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
   484
        (rv == SECSuccess) ? "success" : "failure");
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   485
#endif
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
    return rv;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   488
}
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   489
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   490
/* 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
   491
 * 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
   492
 * 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
   493
 * 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
   494
 * 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
   495
 */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   496
SECStatus
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   497
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
   498
{
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   499
    mp_int Px, Py;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   500
    ECGroup *group = NULL;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   501
    SECStatus rv = SECFailure;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   502
    mp_err err = MP_OKAY;
8175
27e80dc06104 6989705: ECC security code native code compiler warnings
vinnie
parents: 5506
diff changeset
   503
    unsigned int len;
3863
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   504
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   505
    if (!ecParams || !publicValue) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   506
        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
   507
        return SECFailure;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   508
    }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   509
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   510
    /* 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
   511
    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
   512
    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
   513
        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
   514
        return SECFailure;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   515
    } 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
   516
        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
   517
        return SECFailure;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   518
    }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   519
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   520
    MP_DIGITS(&Px) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   521
    MP_DIGITS(&Py) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   522
    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
   523
    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
   524
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   525
    /* Initialize Px and Py */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   526
    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
   527
    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
   528
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   529
    /* construct from named params */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   530
    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
   531
    if (group == NULL) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   532
        /*
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   533
         * 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
   534
         * 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
   535
         * 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
   536
         * 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
   537
         * 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
   538
         * 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
   539
         * 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
   540
         */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   541
        if ((ecParams->name <= ECCurve_noName) ||
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   542
            (ecParams->name >= ECCurve_pastLastCurve)) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   543
            err = MP_BADARG;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   544
        } else {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   545
            err = MP_UNDEF;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   546
        }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   547
        goto cleanup;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   548
    }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   549
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   550
    /* validate public point */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   551
    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
   552
        if (err == MP_NO) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   553
            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
   554
            rv = SECFailure;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   555
            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
   556
        }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   557
        goto cleanup;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   558
    }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   559
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   560
    rv = SECSuccess;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   561
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   562
cleanup:
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   563
    ECGroup_free(group);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   564
    mp_clear(&Px);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   565
    mp_clear(&Py);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   566
    if (err) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   567
        MP_TO_SEC_ERROR(err);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   568
        rv = SECFailure;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   569
    }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   570
    return rv;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   571
}
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
/*
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   574
** 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
   575
** 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
   576
** 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
   577
** 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
   578
** 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
   579
** 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
   580
** 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
   581
** buffer containing the derived secret.
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
SECStatus
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   584
ECDH_Derive(SECItem  *publicValue,
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   585
            ECParams *ecParams,
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   586
            SECItem  *privateValue,
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   587
            PRBool    withCofactor,
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   588
            SECItem  *derivedSecret,
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   589
            int kmflag)
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   590
{
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   591
    SECStatus rv = SECFailure;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   592
    unsigned int len = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   593
    SECItem pointQ = {siBuffer, NULL, 0};
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   594
    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
   595
    mp_int cofactor;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   596
    mp_err err = MP_OKAY;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   597
#if EC_DEBUG
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   598
    int i;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   599
#endif
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   600
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   601
    if (!publicValue || !ecParams || !privateValue ||
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   602
        !derivedSecret) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   603
        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
   604
        return SECFailure;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   605
    }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   606
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   607
    memset(derivedSecret, 0, sizeof *derivedSecret);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   608
    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
   609
    pointQ.len = 2*len + 1;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   610
    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
   611
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   612
    MP_DIGITS(&k) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   613
    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
   614
    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
   615
                                          (mp_size) privateValue->len) );
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   616
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   617
    if (withCofactor && (ecParams->cofactor != 1)) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   618
            /* multiply k with the cofactor */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   619
            MP_DIGITS(&cofactor) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   620
            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
   621
            mp_set(&cofactor, ecParams->cofactor);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   622
            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
   623
    }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   624
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   625
    /* 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
   626
    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
   627
        ec_point_at_infinity(&pointQ))
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   628
        goto cleanup;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   629
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   630
    /* 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
   631
     * 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
   632
     */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   633
    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
   634
    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
   635
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   636
    rv = SECSuccess;
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
#if EC_DEBUG
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   639
    printf("derived_secret:\n");
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   640
    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
   641
        printf("%02x:", derivedSecret->data[i]);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   642
    printf("\n");
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   643
#endif
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
cleanup:
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   646
    mp_clear(&k);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   647
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   648
    if (pointQ.data) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   649
        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
   650
    }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   651
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   652
    return rv;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   653
}
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   654
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   655
/* 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
   656
 * 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
   657
 * computing s).
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   658
 */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   659
SECStatus
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   660
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
   661
    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
   662
{
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   663
    SECStatus rv = SECFailure;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   664
    mp_int x1;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   665
    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
   666
    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
   667
    mp_int n;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   668
    mp_err err = MP_OKAY;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   669
    ECParams *ecParams = NULL;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   670
    SECItem kGpoint = { siBuffer, NULL, 0};
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   671
    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
   672
    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
   673
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   674
#if EC_DEBUG
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   675
    char mpstr[256];
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   676
#endif
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
    /* Initialize MPI integers. */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   679
    /* 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
   680
    MP_DIGITS(&x1) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   681
    MP_DIGITS(&d) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   682
    MP_DIGITS(&k) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   683
    MP_DIGITS(&r) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   684
    MP_DIGITS(&s) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   685
    MP_DIGITS(&n) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   686
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   687
    /* Check args */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   688
    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
   689
        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
   690
        goto cleanup;
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
    ecParams = &(key->ecParams);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   694
    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
   695
    olen = ecParams->order.len;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   696
    if (signature->data == NULL) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   697
        /* 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
   698
        goto finish;
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
    if (signature->len < 2*olen) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   701
        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
   702
        rv = SECBufferTooSmall;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   703
        goto cleanup;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   704
    }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   705
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   706
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   707
    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
   708
    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
   709
    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
   710
    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
   711
    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
   712
    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
   713
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   714
    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
   715
    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
   716
    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
   717
    /* 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
   718
    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
   719
#if EC_DEBUG
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   720
        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
   721
        mp_tohex(&k, mpstr);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   722
        printf("k : %s \n", mpstr);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   723
        mp_tohex(&n, mpstr);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   724
        printf("n : %s \n", mpstr);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   725
#endif
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   726
        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
   727
        goto cleanup;
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
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
    ** 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
   732
    **
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   733
    ** Compute kG
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   734
    */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   735
    kGpoint.len = 2*flen + 1;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   736
    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
   737
    if ((kGpoint.data == NULL) ||
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   738
        (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
   739
            != SECSuccess))
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   740
        goto cleanup;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   741
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
    ** 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
   744
    **
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   745
    ** 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
   746
    */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   747
    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
   748
                                          (mp_size) flen) );
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   749
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   750
    /*
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   751
    ** 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
   752
    **
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   753
    ** 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
   754
    */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   755
    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
   756
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
    ** 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
   759
    **
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   760
    ** verify r != 0
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   761
    */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   762
    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
   763
        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
   764
        goto cleanup;
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
    /*
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   768
    ** 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
   769
    **
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   770
    ** 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
   771
    */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   772
    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
   773
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   774
    /* 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
   775
     * 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
   776
     * (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
   777
    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
   778
        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
   779
    }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   780
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   781
#if EC_DEBUG
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   782
    mp_todecimal(&n, mpstr);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   783
    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
   784
    mp_todecimal(&d, mpstr);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   785
    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
   786
    mp_tohex(&x1, mpstr);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   787
    printf("x1: %s\n", mpstr);
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("digest: %s (decimal)\n", mpstr);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   790
    mp_todecimal(&r, mpstr);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   791
    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
   792
    mp_tohex(&r, mpstr);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   793
    printf("r : %s\n", mpstr);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   794
#endif
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   795
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   796
    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
   797
    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
   798
    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
   799
    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
   800
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   801
#if EC_DEBUG
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   802
    mp_todecimal(&s, mpstr);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   803
    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
   804
    mp_tohex(&s, mpstr);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   805
    printf("s : %s\n", mpstr);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   806
#endif
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
    /*
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   809
    ** 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
   810
    **
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   811
    ** verify s != 0
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
    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
   814
        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
   815
        goto cleanup;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   816
    }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   817
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   818
   /*
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   819
    **
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   820
    ** Signature is tuple (r, s)
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   821
    */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   822
    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
   823
    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
   824
finish:
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   825
    signature->len = 2*olen;
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
    rv = SECSuccess;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   828
    err = MP_OKAY;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   829
cleanup:
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   830
    mp_clear(&x1);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   831
    mp_clear(&d);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   832
    mp_clear(&k);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   833
    mp_clear(&r);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   834
    mp_clear(&s);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   835
    mp_clear(&n);
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
    if (kGpoint.data) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   838
        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
   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
    if (err) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   842
        MP_TO_SEC_ERROR(err);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   843
        rv = SECFailure;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   844
    }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   845
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   846
#if EC_DEBUG
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   847
    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
   848
        (rv == SECSuccess) ? "succeeded" : "failed");
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   849
#endif
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   850
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   851
   return rv;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   852
}
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   853
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   854
/*
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   855
** 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
   856
** and a random seed.
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   857
*/
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   858
SECStatus
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   859
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
   860
    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
   861
{
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   862
    SECStatus rv = SECFailure;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   863
    int len;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   864
    unsigned char *kBytes= NULL;
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
    if (!key) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   867
        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
   868
        return SECFailure;
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
    /* Generate random value k */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   872
    len = key->ecParams.order.len;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   873
    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
   874
        random, randomLen, kmflag);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   875
    if (kBytes == NULL) goto cleanup;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   876
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   877
    /* 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
   878
    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
   879
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   880
cleanup:
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   881
    if (kBytes) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   882
        PORT_ZFree(kBytes, len * 2);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   883
    }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   884
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   885
#if EC_DEBUG
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   886
    printf("ECDSA signing %s\n",
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   887
        (rv == SECSuccess) ? "succeeded" : "failed");
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   888
#endif
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   889
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   890
    return rv;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   891
}
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   892
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   893
/*
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   894
** 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
   895
*/
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   896
SECStatus
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   897
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
   898
                 const SECItem *digest, int kmflag)
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   899
{
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   900
    SECStatus rv = SECFailure;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   901
    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
   902
    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
   903
    mp_int x1;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   904
    mp_int n;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   905
    mp_err err = MP_OKAY;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   906
    ECParams *ecParams = NULL;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   907
    SECItem pointC = { siBuffer, NULL, 0 };
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   908
    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
   909
    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
   910
    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
   911
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   912
#if EC_DEBUG
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   913
    char mpstr[256];
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   914
    printf("ECDSA verification called\n");
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   915
#endif
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   916
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   917
    /* Initialize MPI integers. */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   918
    /* 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
   919
    MP_DIGITS(&r_) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   920
    MP_DIGITS(&s_) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   921
    MP_DIGITS(&c) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   922
    MP_DIGITS(&u1) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   923
    MP_DIGITS(&u2) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   924
    MP_DIGITS(&x1) = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   925
    MP_DIGITS(&v)  = 0;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   926
    MP_DIGITS(&n)  = 0;
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
    /* Check args */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   929
    if (!key || !signature || !digest) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   930
        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
   931
        goto cleanup;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   932
    }
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
    ecParams = &(key->ecParams);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   935
    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
   936
    olen = ecParams->order.len;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   937
    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
   938
        signature->len > 2*olen) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   939
        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
   940
        goto cleanup;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   941
    }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   942
    slen = signature->len/2;
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
    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
   945
    if (pointC.data == NULL)
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   946
        goto cleanup;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   947
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   948
    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
   949
    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
   950
    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
   951
    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
   952
    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
   953
    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
   954
    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
   955
    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
   956
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   957
    /*
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   958
    ** 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
   959
    */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   960
    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
   961
    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
   962
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
    ** 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
   965
    **
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   966
    ** 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
   967
    */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   968
    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
   969
    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
   970
        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
   971
        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
   972
        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
   973
    }
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
    /*
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   976
    ** 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
   977
    **
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   978
    ** c = (s')**-1 mod n
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   979
    */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   980
    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
   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
    ** 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
   984
    **
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   985
    ** 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
   986
    */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   987
    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
   988
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   989
    /* 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
   990
     * 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
   991
     * (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
   992
    /* u1 = HASH(M')     */
27e80dc06104 6989705: ECC security code native code compiler warnings
vinnie
parents: 5506
diff changeset
   993
    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
   994
        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
   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
#if EC_DEBUG
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   998
    mp_todecimal(&r_, mpstr);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
   999
    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
  1000
    mp_todecimal(&s_, mpstr);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1001
    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
  1002
    mp_todecimal(&c, mpstr);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1003
    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
  1004
    mp_todecimal(&u1, mpstr);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1005
    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
  1006
#endif
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1007
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1008
    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
  1009
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1010
    /*
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1011
    ** 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
  1012
    **
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1013
    ** u2 = ((r') * c) mod n
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
    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
  1016
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1017
    /*
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1018
    ** 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
  1019
    **
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1020
    ** Compute u1*G + u2*Q
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1021
    ** 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
  1022
    ** 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
  1023
    */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1024
    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
  1025
        != SECSuccess) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1026
        rv = SECFailure;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1027
        goto cleanup;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1028
    }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1029
    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
  1030
        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
  1031
        rv = SECFailure;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1032
        goto cleanup;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1033
    }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1034
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1035
    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
  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 2
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
    ** v = x1 mod n
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
    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
  1043
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1044
#if EC_DEBUG
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1045
    mp_todecimal(&r_, mpstr);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1046
    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
  1047
    mp_todecimal(&v, mpstr);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1048
    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
  1049
#endif
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1050
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1051
    /*
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1052
    ** 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
  1053
    **
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1054
    ** Verification:  v == r'
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1055
    */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1056
    if (mp_cmp(&v, &r_)) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1057
        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
  1058
        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
  1059
    } else {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1060
        rv = SECSuccess; /* Signature verified. */
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1061
    }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1062
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1063
#if EC_DEBUG
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1064
    mp_todecimal(&u1, mpstr);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1065
    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
  1066
    mp_todecimal(&u2, mpstr);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1067
    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
  1068
    mp_tohex(&x1, mpstr);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1069
    printf("x1: %s\n", mpstr);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1070
    mp_todecimal(&v, mpstr);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1071
    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
  1072
#endif
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1073
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1074
cleanup:
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1075
    mp_clear(&r_);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1076
    mp_clear(&s_);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1077
    mp_clear(&c);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1078
    mp_clear(&u1);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1079
    mp_clear(&u2);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1080
    mp_clear(&x1);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1081
    mp_clear(&v);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1082
    mp_clear(&n);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1083
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1084
    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
  1085
    if (err) {
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1086
        MP_TO_SEC_ERROR(err);
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1087
        rv = SECFailure;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1088
    }
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1089
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1090
#if EC_DEBUG
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1091
    printf("ECDSA verification %s\n",
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1092
        (rv == SECSuccess) ? "succeeded" : "failed");
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1093
#endif
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1094
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1095
    return rv;
8e0f58b1c072 6884175: CR cleanup for 6840752: Provide out-of-the-box support for ECC algorithms
vinnie
parents:
diff changeset
  1096
}