/**
* \file rsa.h
*
- * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
+ * Copyright (C) 2006-2010, Brainspark B.V.
*
- * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ * All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-/* $Cambridge: exim/src/src/pdkim/rsa.h,v 1.2 2009/06/10 07:34:05 tom Exp $ */
-
#ifndef POLARSSL_RSA_H
#define POLARSSL_RSA_H
#include "bignum.h"
+/*
+ * RSA Error codes
+ */
#define POLARSSL_ERR_RSA_BAD_INPUT_DATA -0x0400
#define POLARSSL_ERR_RSA_INVALID_PADDING -0x0410
#define POLARSSL_ERR_RSA_KEY_GEN_FAILED -0x0420
#define POLARSSL_ERR_RSA_PUBLIC_FAILED -0x0440
#define POLARSSL_ERR_RSA_PRIVATE_FAILED -0x0450
#define POLARSSL_ERR_RSA_VERIFY_FAILED -0x0460
-#define POLARSSL_ERR_RSA_OUTPUT_TO_LARGE -0x0470
+#define POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE -0x0470
+#define POLARSSL_ERR_RSA_RNG_FAILED -0x0480
-#define POLARSSL_ERR_ASN1_OUT_OF_DATA -0x0014
-#define POLARSSL_ERR_ASN1_UNEXPECTED_TAG -0x0016
-#define POLARSSL_ERR_ASN1_INVALID_LENGTH -0x0018
-#define POLARSSL_ERR_ASN1_LENGTH_MISMATCH -0x001A
-#define POLARSSL_ERR_ASN1_INVALID_DATA -0x001C
+/* *************** begin copy from x509.h ************************/
+/*
+ * ASN1 Error codes
+ *
+ * These error codes will be OR'ed to X509 error codes for
+ * higher error granularity.
+ */
+#define POLARSSL_ERR_ASN1_OUT_OF_DATA 0x0014
+#define POLARSSL_ERR_ASN1_UNEXPECTED_TAG 0x0016
+#define POLARSSL_ERR_ASN1_INVALID_LENGTH 0x0018
+#define POLARSSL_ERR_ASN1_LENGTH_MISMATCH 0x001A
+#define POLARSSL_ERR_ASN1_INVALID_DATA 0x001C
+/*
+ * X509 Error codes
+ */
#define POLARSSL_ERR_X509_FEATURE_UNAVAILABLE -0x0020
#define POLARSSL_ERR_X509_CERT_INVALID_PEM -0x0040
#define POLARSSL_ERR_X509_CERT_INVALID_FORMAT -0x0060
#define ASN1_T61_STRING 0x14
#define ASN1_IA5_STRING 0x16
#define ASN1_UTC_TIME 0x17
+#define ASN1_GENERALIZED_TIME 0x18
#define ASN1_UNIVERSAL_STRING 0x1C
#define ASN1_BMP_STRING 0x1E
#define ASN1_PRIMITIVE 0x00
#define ASN1_CONSTRUCTED 0x20
#define ASN1_CONTEXT_SPECIFIC 0x80
+/* *************** end copy from x509.h ************************/
/*
* PKCS#1 constants
*/
-#define RSA_RAW 0
-#define RSA_MD2 2
-#define RSA_MD4 3
-#define RSA_MD5 4
-#define RSA_SHA1 5
-#define RSA_SHA256 6
+#define SIG_RSA_RAW 0
+#define SIG_RSA_MD2 2
+#define SIG_RSA_MD4 3
+#define SIG_RSA_MD5 4
+#define SIG_RSA_SHA1 5
+#define SIG_RSA_SHA224 14
+#define SIG_RSA_SHA256 11
+#define SIG_RSA_SHA384 12
+#define SIG_RSA_SHA512 13
#define RSA_PUBLIC 0
#define RSA_PRIVATE 1
#define RSA_SIGN 1
#define RSA_CRYPT 2
+#define ASN1_STR_CONSTRUCTED_SEQUENCE "\x30"
+#define ASN1_STR_NULL "\x05"
+#define ASN1_STR_OID "\x06"
+#define ASN1_STR_OCTET_STRING "\x04"
+
+#define OID_DIGEST_ALG_MDX "\x2A\x86\x48\x86\xF7\x0D\x02\x00"
+#define OID_HASH_ALG_SHA1 "\x2b\x0e\x03\x02\x1a"
+#define OID_HASH_ALG_SHA2X "\x60\x86\x48\x01\x65\x03\x04\x02\x00"
+
+#define OID_ISO_MEMBER_BODIES "\x2a"
+#define OID_ISO_IDENTIFIED_ORG "\x2b"
+
+/*
+ * ISO Member bodies OID parts
+ */
+#define OID_COUNTRY_US "\x86\x48"
+#define OID_RSA_DATA_SECURITY "\x86\xf7\x0d"
+
+/*
+ * ISO Identified organization OID parts
+ */
+#define OID_OIW_SECSIG_SHA1 "\x0e\x03\x02\x1a"
+
/*
* DigestInfo ::= SEQUENCE {
* digestAlgorithm DigestAlgorithmIdentifier,
*
* Digest ::= OCTET STRING
*/
-#define ASN1_HASH_MDX \
- "\x30\x20\x30\x0C\x06\x08\x2A\x86\x48" \
- "\x86\xF7\x0D\x02\x00\x05\x00\x04\x10"
-
-#define ASN1_HASH_SHA1 \
- "\x30\x21\x30\x09\x06\x05\x2B\x0E\x03" \
- "\x02\x1A\x05\x00\x04\x14"
-
-#define ASN1_HASH_SHA256 \
- "\x30\x31\x30\x0d\x06\x09\x60\x86\x48" \
- "\x01\x65\x03\x04\x02\x01\x05\x00\x04" \
- "\x20"
+#define ASN1_HASH_MDX \
+( \
+ ASN1_STR_CONSTRUCTED_SEQUENCE "\x20" \
+ ASN1_STR_CONSTRUCTED_SEQUENCE "\x0C" \
+ ASN1_STR_OID "\x08" \
+ OID_DIGEST_ALG_MDX \
+ ASN1_STR_NULL "\x00" \
+ ASN1_STR_OCTET_STRING "\x10" \
+)
+
+#define ASN1_HASH_SHA1 \
+ ASN1_STR_CONSTRUCTED_SEQUENCE "\x21" \
+ ASN1_STR_CONSTRUCTED_SEQUENCE "\x09" \
+ ASN1_STR_OID "\x05" \
+ OID_HASH_ALG_SHA1 \
+ ASN1_STR_NULL "\x00" \
+ ASN1_STR_OCTET_STRING "\x14"
+
+#define ASN1_HASH_SHA2X \
+ ASN1_STR_CONSTRUCTED_SEQUENCE "\x11" \
+ ASN1_STR_CONSTRUCTED_SEQUENCE "\x0d" \
+ ASN1_STR_OID "\x09" \
+ OID_HASH_ALG_SHA2X \
+ ASN1_STR_NULL "\x00" \
+ ASN1_STR_OCTET_STRING "\x00"
/**
* \brief RSA context structure
int padding; /*!< 1.5 or OAEP/PSS */
int hash_id; /*!< hash identifier */
- int (*f_rng)(void *); /*!< RNG function */
- void *p_rng; /*!< RNG parameter */
}
rsa_context;
* \param ctx RSA context to be initialized
* \param padding RSA_PKCS_V15 or RSA_PKCS_V21
* \param hash_id RSA_PKCS_V21 hash identifier
- * \param f_rng RNG function
- * \param p_rng RNG parameter
*
* \note The hash_id parameter is actually ignored
* when using RSA_PKCS_V15 padding.
*
- * \note Currently (xyssl-0.8), RSA_PKCS_V21 padding
+ * \note Currently, RSA_PKCS_V21 padding
* is not supported.
*/
void rsa_init( rsa_context *ctx,
int padding,
- int hash_id,
- int (*f_rng)(void *),
- void *p_rng );
+ int hash_id);
/**
* \brief Generate an RSA keypair
*
* \param ctx RSA context that will hold the key
+ * \param f_rng RNG function
+ * \param p_rng RNG parameter
* \param nbits size of the public key in bits
* \param exponent public exponent (e.g., 65537)
*
* \note rsa_init() must be called beforehand to setup
- * the RSA context (especially f_rng and p_rng).
+ * the RSA context.
*
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
*/
-int rsa_gen_key( rsa_context *ctx, int nbits, int exponent );
+int rsa_gen_key( rsa_context *ctx,
+ int (*f_rng)(void *),
+ void *p_rng,
+ int nbits, int exponent );
/**
* \brief Check a public RSA key
*
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
*/
-int rsa_check_pubkey( rsa_context *ctx );
+int rsa_check_pubkey( const rsa_context *ctx );
/**
* \brief Check a private RSA key
*
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
*/
-int rsa_check_privkey( rsa_context *ctx );
+int rsa_check_privkey( const rsa_context *ctx );
/**
* \brief Do an RSA public key operation
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
*
* \note This function does NOT take care of message
- * padding. Also, be sure to set input[0] = 0.
+ * padding. Also, be sure to set input[0] = 0 or assure that
+ * input is smaller than N.
*
* \note The input and output buffers must be large
* enough (eg. 128 bytes if RSA-1024 is used).
*/
int rsa_public( rsa_context *ctx,
- unsigned char *input,
+ const unsigned char *input,
unsigned char *output );
/**
* enough (eg. 128 bytes if RSA-1024 is used).
*/
int rsa_private( rsa_context *ctx,
- unsigned char *input,
+ const unsigned char *input,
unsigned char *output );
/**
* \brief Add the message padding, then do an RSA operation
*
* \param ctx RSA context
+ * \param f_rng RNG function
+ * \param p_rng RNG parameter
* \param mode RSA_PUBLIC or RSA_PRIVATE
- * \param ilen contains the the plaintext length
+ * \param ilen contains the plaintext length
* \param input buffer holding the data to be encrypted
* \param output buffer that will hold the ciphertext
*
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
*/
int rsa_pkcs1_encrypt( rsa_context *ctx,
+ int (*f_rng)(void *),
+ void *p_rng,
int mode, int ilen,
- unsigned char *input,
+ const unsigned char *input,
unsigned char *output );
/**
* \param input buffer holding the encrypted data
* \param output buffer that will hold the plaintext
* \param olen will contain the plaintext length
- * \param output_max_len maximum length of the output buffer
+ * \param output_max_len maximum length of the output buffer
*
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
*
*/
int rsa_pkcs1_decrypt( rsa_context *ctx,
int mode, int *olen,
- unsigned char *input,
+ const unsigned char *input,
unsigned char *output,
- int output_max_len);
+ int output_max_len );
/**
* \brief Do a private RSA to sign a message digest
*
* \param ctx RSA context
* \param mode RSA_PUBLIC or RSA_PRIVATE
- * \param hash_id RSA_RAW, RSA_MD{2,4,5} or RSA_SHA{1,256}
- * \param hashlen message digest length (for RSA_RAW only)
+ * \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
+ * \param hashlen message digest length (for SIG_RSA_RAW only)
* \param hash buffer holding the message digest
* \param sig buffer that will hold the ciphertext
*
int mode,
int hash_id,
int hashlen,
- unsigned char *hash,
+ const unsigned char *hash,
unsigned char *sig );
/**
*
* \param ctx points to an RSA public key
* \param mode RSA_PUBLIC or RSA_PRIVATE
- * \param hash_id RSA_RAW, RSA_MD{2,4,5} or RSA_SHA{1,256}
- * \param hashlen message digest length (for RSA_RAW only)
+ * \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
+ * \param hashlen message digest length (for SIG_RSA_RAW only)
* \param hash buffer holding the message digest
* \param sig buffer holding the ciphertext
*
int mode,
int hash_id,
int hashlen,
- unsigned char *hash,
+ const unsigned char *hash,
unsigned char *sig );
/**
* \brief Free the components of an RSA key
+ *
+ * \param ctx RSA Context to free
*/
void rsa_free( rsa_context *ctx );
+/* PDKIM declarations (not part of polarssl) */
int rsa_parse_public_key( rsa_context *rsa, unsigned char *buf, int buflen );
-
int rsa_parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
unsigned char *pwd, int pwdlen );
+
#ifdef __cplusplus
}
#endif