softDSA.c revision c64d15a587b6038b85a928885fc997da7315fbfe
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <security/cryptoki.h>
#include <bignum.h>
#include "softGlobal.h"
#include "softSession.h"
#include "softObject.h"
#include "softDSA.h"
#include "softRandom.h"
#include "softOps.h"
#include "softMAC.h"
#include "softCrypt.h"
/*
* Allocate a DSA context for the active sign or verify operation.
* This function is called without the session lock held.
*/
{
if (sign) {
return (CKR_KEY_TYPE_INCONSISTENT);
} else {
return (CKR_KEY_TYPE_INCONSISTENT);
}
return (rv);
}
return (CKR_HOST_MEMORY);
}
/*
* Make a copy of the signature or verification key, and save it
* in the DSA crypto context since it will be used later for
* signing/verification. We don't want to hold any object reference
* on this original key while doing signing/verification.
*/
NULL);
/* Most likely we ran out of space. */
return (rv);
}
/* No need to hold the lock on the old object. */
if (sign) {
} else {
}
return (CKR_OK);
}
/* size is in bits */
{
return (err);
goto ret1;
goto ret2;
goto ret3;
goto ret4;
goto ret5;
goto ret6;
goto ret7;
goto ret8;
return (BIG_OK);
ret8:
big_finish(&(key->s));
ret7:
big_finish(&(key->r));
ret6:
big_finish(&(key->k));
ret5:
big_finish(&(key->y));
ret4:
big_finish(&(key->x));
ret3:
big_finish(&(key->g));
ret2:
big_finish(&(key->p));
ret1:
big_finish(&(key->q));
return (err);
}
void
{
big_finish(&(key->v));
big_finish(&(key->s));
big_finish(&(key->r));
big_finish(&(key->k));
big_finish(&(key->y));
big_finish(&(key->x));
big_finish(&(key->g));
big_finish(&(key->p));
big_finish(&(key->q));
}
{
goto clean1;
}
if (20 != qlen) {
goto clean1;
}
goto clean1;
}
goto clean1;
}
goto clean1;
}
goto clean1;
}
if (20 < xlen) {
goto clean1;
}
goto clean1;
}
goto clean6;
}
goto clean7;
}
goto clean8;
}
goto clean9;
}
goto clean10;
goto clean10;
goto clean10;
goto clean10;
goto clean10;
goto clean10; /* tmp <- k^-1 */
goto clean10;
goto clean10;
goto clean10;
goto clean10;
big_finish(&tmp2);
big_finish(&tmp1);
big_finish(&tmp);
big_finish(&msg);
else if (err == BIG_NO_MEM)
else
return (rv);
}
{
goto clean1;
}
if (20 != qlen) {
goto clean1;
}
goto clean1;
}
goto clean1;
}
goto clean1;
}
goto clean1;
}
goto clean1;
}
goto clean1;
}
goto clean6;
}
goto clean7;
}
goto clean8;
}
goto clean9;
}
goto clean10;
goto clean10; /* tmp2 <- w */
goto clean10;
goto clean10; /* tmp1 <- u_1 */
goto clean10;
goto clean10; /* tmp2 <- u_2 */
goto clean10;
goto clean10;
goto clean10;
goto clean10;
goto clean10;
else
big_finish(&tmp3);
big_finish(&tmp2);
big_finish(&tmp1);
big_finish(&msg);
return (rv);
}
{
/* Check arguments before performing message digest. */
/* Application asks for the length of the output buffer. */
goto clean1;
}
/* Is the application-supplied buffer large enough? */
if (*pulSignedLen < DSA_SIGNATURE_LENGTH) {
goto clean1;
}
if (Final) {
} else {
}
/* free the signature key */
goto clean_exit;
}
/*
* Now, we are ready to sign the data
* soft_dsa_sign() will free the signature key.
*/
/* soft_digest_common() has freed the digest context */
return (rv);
}
{
goto clean_exit;
}
/* Output length is always 40 bytes. */
/* Application asks for the length of the output buffer. */
return (CKR_OK);
}
/* Input data length needs to be 20 bytes. */
if (ulDataLen != 20) {
goto clean_exit;
}
if (*pulSignedLen < DSA_SIGNATURE_LENGTH) {
return (CKR_BUFFER_TOO_SMALL);
}
}
return (rv);
}
{
goto clean_exit;
}
/* The signature length is always 40 bytes. */
if (ulSignatureLen != DSA_SIGNATURE_LENGTH) {
goto clean_exit;
}
/* Input data length needs to be 20 bytes. */
if (ulDataLen != 20) {
goto clean_exit;
}
return (rv);
}
{
if (Final) {
} else {
}
/* free the verification key */
goto clean_exit;
}
/*
* Now, we are ready to verify the data using signature.
* soft_dsa_verify() will free the verification key.
*/
/* soft_digest_common() has freed the digest context */
return (rv);
}
{
switch (type) {
case CKA_VALUE:
if (public)
else
break;
case CKA_PRIME:
if (public)
else
break;
case CKA_SUBPRIME:
if (public)
else
break;
case CKA_BASE:
if (public)
else
break;
}
goto cleanexit;
}
/* Copy the attribute in the key object. */
/* No need to free big_value because dst holds it now after copy. */
return (rv);
}
{
do {
return (convert_rv(err));
}
return (convert_rv(err));
return (CKR_OK);
}
{
return (CKR_ARGUMENTS_BAD);
}
/* lookup prime, subprime and base */
goto cleanexit;
}
if ((prime_len < MIN_DSA_KEY_LEN) ||
(prime_len > MAX_DSA_KEY_LEN)) {
goto cleanexit;
}
&subprime_len);
goto cleanexit;
}
if (subprime_len != DSA_SUBPRIME_BYTES) {
goto cleanexit;
}
goto cleanexit;
}
/*
* initialize the dsa key
* Note: big_extend takes length in words
*/
goto cleanexit;
}
goto cleanexit;
}
BIG_OK) {
goto cleanexit;
}
BIG_OK) {
goto cleanexit;
}
/*
* generate DSA key pair
* Note: bignum.len is length of value in words
*/
goto cleanexit;
}
goto cleanexit;
}
goto cleanexit;
}
/* Update attribute in public key. */
goto cleanexit;
}
/* Update attributes in private key. */
goto cleanexit;
}
goto cleanexit;
}
goto cleanexit;
}
goto cleanexit;
}
}
}
return (rv);
}