pk.h 14.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
/**
 * \file pk.h
 *
 * \brief Public Key abstraction layer
 *
 *  Copyright (C) 2006-2013, Brainspark B.V.
 *
 *  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
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
27

28 29 30
#ifndef POLARSSL_PK_H
#define POLARSSL_PK_H

31 32
#include "config.h"

33 34
#include "md.h"

35 36 37 38
#if defined(POLARSSL_RSA_C)
#include "rsa.h"
#endif

39 40 41 42
#if defined(POLARSSL_ECP_C)
#include "ecp.h"
#endif

43 44 45 46
#if defined(POLARSSL_ECDSA_C)
#include "ecdsa.h"
#endif

47
#define POLARSSL_ERR_PK_MALLOC_FAILED       -0x2F80  /**< Memory alloation failed. */
48
#define POLARSSL_ERR_PK_TYPE_MISMATCH       -0x2F00  /**< Type mismatch, eg attempt to encrypt with an ECDSA key */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
49
#define POLARSSL_ERR_PK_BAD_INPUT_DATA      -0x2E80  /**< Bad input parameters to function. */
50 51 52 53 54 55 56 57 58 59 60
#define POLARSSL_ERR_PK_FILE_IO_ERROR       -0x2E00  /**< Read/write of file failed. */
#define POLARSSL_ERR_PK_KEY_INVALID_VERSION -0x2D80  /**< Unsupported key version */
#define POLARSSL_ERR_PK_KEY_INVALID_FORMAT  -0x2D00  /**< Invalid key tag or value. */
#define POLARSSL_ERR_PK_UNKNOWN_PK_ALG      -0x2C80  /**< Key algorithm is unsupported (only RSA and EC are supported). */
#define POLARSSL_ERR_PK_PASSWORD_REQUIRED   -0x2C00  /**< Private key password can't be empty. */
#define POLARSSL_ERR_PK_PASSWORD_MISMATCH   -0x2B80  /**< Given private key password does not allow for correct decryption. */
#define POLARSSL_ERR_PK_INVALID_PUBKEY      -0x2B00  /**< The pubkey tag or value is invalid (only RSA and EC are supported). */
#define POLARSSL_ERR_PK_INVALID_ALG         -0x2A80  /**< The algorithm tag or value is invalid. */
#define POLARSSL_ERR_PK_UNKNOWN_NAMED_CURVE -0x2A00  /**< Elliptic curve is unsupported (only NIST curves are supported). */
#define POLARSSL_ERR_PK_FEATURE_UNAVAILABLE -0x2980  /**< Unavailable feature, e.g. RSA disabled for RSA key. */

61

62 63 64 65 66 67 68
#if defined(POLARSSL_RSA_C)
/**
 * Quick access to an RSA context inside a PK context.
 *
 * \warning You must make sure the PK context actually holds an RSA context
 * before using this macro!
 */
69
#define pk_rsa( pk )        ( (rsa_context *) (pk).pk_ctx )
70
#endif /* POLARSSL_RSA_C */
71 72 73 74 75 76 77 78

#if defined(POLARSSL_ECP_C)
/**
 * Quick access to an EC context inside a PK context.
 *
 * \warning You must make sure the PK context actually holds an EC context
 * before using this macro!
 */
79
#define pk_ec( pk )         ( (ecp_keypair *) (pk).pk_ctx )
80
#endif /* POLARSSL_ECP_C */
81 82


83 84 85 86 87 88 89 90 91 92
#ifdef __cplusplus
extern "C" {
#endif

/**
 * \brief          Public key types
 */
typedef enum {
    POLARSSL_PK_NONE=0,
    POLARSSL_PK_RSA,
93 94
    POLARSSL_PK_ECKEY,
    POLARSSL_PK_ECKEY_DH,
95
    POLARSSL_PK_ECDSA,
96
    POLARSSL_PK_RSA_ALT,
97 98
} pk_type_t;

99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
/**
 * \brief           Types for interfacing with the debug module
 */
typedef enum
{
    POLARSSL_PK_DEBUG_NONE = 0,
    POLARSSL_PK_DEBUG_MPI,
    POLARSSL_PK_DEBUG_ECP,
} pk_debug_type;

/**
 * \brief           Item to send to the debug module
 */
typedef struct
{
    pk_debug_type type;
    char *name;
    void *value;
} pk_debug_item;

/** Maximum number of item send for debugging, plus 1 */
#define POLARSSL_PK_DEBUG_MAX_ITEMS 3

122
/**
123
 * \brief           Public key information and operations
124 125 126 127 128 129
 */
typedef struct
{
    /** Public key type */
    pk_type_t type;

130 131 132 133
    /** Type name */
    const char *name;

    /** Get key size in bits */
134
    size_t (*get_size)( const void * );
135

136 137 138
    /** Tell if the context implements this type (eg ECKEY can do ECDSA) */
    int (*can_do)( pk_type_t type );

139
    /** Verify signature */
140 141
    int (*verify_func)( void *ctx, md_type_t md_alg,
                        const unsigned char *hash, size_t hash_len,
142
                        const unsigned char *sig, size_t sig_len );
143

144 145 146 147 148 149 150
    /** Make signature */
    int (*sign_func)( void *ctx, md_type_t md_alg,
                      const unsigned char *hash, size_t hash_len,
                      unsigned char *sig, size_t *sig_len,
                      int (*f_rng)(void *, unsigned char *, size_t),
                      void *p_rng );

151 152 153 154 155 156 157 158 159 160 161 162
    /** Decrypt message */
    int (*decrypt_func)( void *ctx, const unsigned char *input, size_t ilen,
                         unsigned char *output, size_t *olen, size_t osize,
                         int (*f_rng)(void *, unsigned char *, size_t),
                         void *p_rng );

    /** Encrypt message */
    int (*encrypt_func)( void *ctx, const unsigned char *input, size_t ilen,
                         unsigned char *output, size_t *olen, size_t osize,
                         int (*f_rng)(void *, unsigned char *, size_t),
                         void *p_rng );

163 164 165 166 167 168
    /** Allocate a new context */
    void * (*ctx_alloc_func)( void );

    /** Free the given context */
    void (*ctx_free_func)( void *ctx );

169 170 171
    /** Interface with the debug module */
    void (*debug_func)( const void *ctx, pk_debug_item *items );

172 173
} pk_info_t;

174 175 176 177 178
/**
 * \brief           Public key container
 */
typedef struct
{
179 180
    const pk_info_t *   pk_info;    /**< Public key informations        */
    void *              pk_ctx;     /**< Underlying public key context  */
181 182
} pk_context;

183 184 185 186 187 188 189 190 191 192 193 194
/**
 * \brief           Types for RSA-alt abstraction
 */
typedef int (*pk_rsa_alt_decrypt_func)( void *ctx, int mode, size_t *olen,
                    const unsigned char *input, unsigned char *output,
                    size_t output_max_len );
typedef int (*pk_rsa_alt_sign_func)( void *ctx,
                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
                    int mode, int hash_id, unsigned int hashlen,
                    const unsigned char *hash, unsigned char *sig );
typedef size_t (*pk_rsa_alt_key_len_func)( void *ctx );

195
/**
196 197
 * \brief           Return information associated with the given PK type
 *
198
 * \param pk_type   PK type to search for.
199 200
 *
 * \return          The PK info associated with the type or NULL if not found.
201
 */
202
const pk_info_t *pk_info_from_type( pk_type_t pk_type );
203 204

/**
205
 * \brief           Initialize a pk_context (as NONE)
206
 */
207
void pk_init( pk_context *ctx );
208

209 210 211 212 213
/**
 * \brief           Free a pk_context
 */
void pk_free( pk_context *ctx );

214
/**
215 216
 * \brief           Initialize a PK context with the information given
 *                  and allocates the type-specific PK subcontext.
217
 *
218 219
 * \param ctx       Context to initialize. Must be empty (type NONE).
 * \param info      Information to use
220
 *
221 222 223
 * \return          0 on success,
 *                  POLARSSL_ERR_PK_BAD_INPUT_DATA on invalid input,
 *                  POLARSSL_ERR_PK_MALLOC_FAILED on allocation failure.
224 225 226
 *
 * \note            For contexts holding an RSA-alt key, use
 *                  \c pk_init_ctx_rsa_alt() instead.
227
 */
228 229 230
int pk_init_ctx( pk_context *ctx, const pk_info_t *info );

/**
231 232 233 234 235 236 237 238 239 240 241 242
 * \brief           Initialiaze an RSA-alt context
 *
 * \param ctx       Context to initialize. Must be empty (type NONE).
 * \param key       RSA key pointer
 * \param decrypt_func  Decryption function
 * \param sign_func     Signing function
 * \param key_len_func  Function returning key length
 *
 * \return          0 on success, or POLARSSL_ERR_PK_BAD_INPUT_DATA if the
 *                  context wasn't already initialized as RSA_ALT.
 *
 * \note            This function replaces \c pk_init_ctx() for RSA-alt.
243
 */
244 245 246 247
int pk_init_ctx_rsa_alt( pk_context *ctx, void * key,
                         pk_rsa_alt_decrypt_func decrypt_func,
                         pk_rsa_alt_sign_func sign_func,
                         pk_rsa_alt_key_len_func key_len_func );
248

249 250 251 252 253 254 255 256 257
/**
 * \brief           Get the size in bits of the underlying key
 *
 * \param ctx       Context to use
 *
 * \return          Key size in bits, or 0 on error
 */
size_t pk_get_size( const pk_context *ctx );

258 259 260 261 262 263
/**
 * \brief           Get the length in bytes of the underlying key
 * \param ctx       Context to use
 *
 * \return          Key lenght in bytes, or 0 on error
 */
264
static inline size_t pk_get_len( const pk_context *ctx )
265 266 267 268
{
    return( ( pk_get_size( ctx ) + 7 ) / 8 );
}

269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
/**
 * \brief           Tell if a context can do the operation given by type
 *
 * \param ctx       Context to test
 * \param type      Target type
 *
 * \return          0 if context can't do the operations,
 *                  1 otherwise.
 */
int pk_can_do( pk_context *ctx, pk_type_t type );

/**
 * \brief           Verify signature
 *
 * \param ctx       PK context to use
284
 * \param md_alg    Hash algorithm used (see notes)
285
 * \param hash      Hash of the message to sign
286
 * \param hash_len  Hash length or 0 (see notes)
287 288 289 290 291
 * \param sig       Signature to verify
 * \param sig_len   Signature length
 *
 * \return          0 on success (signature is valid),
 *                  or a specific error code.
292 293 294 295 296
 *
 * \note            If hash_len is 0, then the length associated with md_alg
 *                  is used instead, or an error returned if it is invalid.
 *
 * \note            md_alg may be POLARSSL_MD_NONE, only if hash_len != 0
297
 */
298 299
int pk_verify( pk_context *ctx, md_type_t md_alg,
               const unsigned char *hash, size_t hash_len,
300 301
               const unsigned char *sig, size_t sig_len );

302 303 304 305
/**
 * \brief           Make signature
 *
 * \param ctx       PK context to use
306
 * \param md_alg    Hash algorithm used (see notes)
307
 * \param hash      Hash of the message to sign
308
 * \param hash_len  Hash length or 0 (see notes)
309 310 311 312 313 314
 * \param sig       Place to write the signature
 * \param sig_len   Number of bytes written
 * \param f_rng     RNG function
 * \param p_rng     RNG parameter
 *
 * \return          0 on success, or a specific error code.
315 316 317 318 319
 *
 * \note            If hash_len is 0, then the length associated with md_alg
 *                  is used instead, or an error returned if it is invalid.
 *
 * \note            md_alg may be POLARSSL_MD_NONE, only if hash_len != 0
320 321 322 323 324 325
 */
int pk_sign( pk_context *ctx, md_type_t md_alg,
             const unsigned char *hash, size_t hash_len,
             unsigned char *sig, size_t *sig_len,
             int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );

326 327 328 329 330 331 332 333 334
/**
 * \brief           Decrypt message
 *
 * \param ctx       PK context to use
 * \param input     Input to decrypt
 * \param ilen      Input size
 * \param output    Decrypted output
 * \param olen      Decrypted message lenght
 * \param osize     Size of the output buffer
335 336
 * \param f_rng     RNG function
 * \param p_rng     RNG parameter
337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353
 *
 * \return          0 on success, or a specific error code.
 */
int pk_decrypt( pk_context *ctx,
                const unsigned char *input, size_t ilen,
                unsigned char *output, size_t *olen, size_t osize,
                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );

/**
 * \brief           Encrypt message
 *
 * \param ctx       PK context to use
 * \param input     Message to encrypt
 * \param ilen      Message size
 * \param output    Encrypted output
 * \param olen      Encrypted output length
 * \param osize     Size of the output buffer
354 355
 * \param f_rng     RNG function
 * \param p_rng     RNG parameter
356 357 358 359 360 361 362 363
 *
 * \return          0 on success, or a specific error code.
 */
int pk_encrypt( pk_context *ctx,
                const unsigned char *input, size_t ilen,
                unsigned char *output, size_t *olen, size_t osize,
                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );

364 365 366 367 368 369 370 371 372 373
/**
 * \brief           Export debug information
 *
 * \param ctx       Context to use
 * \param items     Place to write debug items
 *
 * \return          0 on sucess or POLARSSL_ERR_PK_BAD_INPUT_DATA
 */
int pk_debug( const pk_context *ctx, pk_debug_item *items );

374 375 376 377 378 379 380 381 382
/**
 * \brief           Access the type name
 *
 * \param ctx       Context to use
 *
 * \return          Type name on success, or "invalid PK"
 */
const char * pk_get_name( const pk_context *ctx );

383 384 385 386 387 388 389 390 391
/**
 * \brief           Get the key typee
 *
 * \param ctx       Context to use
 *
 * \return          Type on success, or POLARSSL_PK_NONE
 */
pk_type_t pk_get_type( const pk_context *ctx );

392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460
/** \ingroup x509_module */
/**
 * \brief           Parse a private key
 *
 * \param ctx       key to be initialized
 * \param key       input buffer
 * \param keylen    size of the buffer
 * \param pwd       password for decryption (optional)
 * \param pwdlen    size of the password
 *
 * \return          0 if successful, or a specific PK or PEM error code
 */
int pk_parse_key( pk_context *ctx,
                  const unsigned char *key, size_t keylen,
                  const unsigned char *pwd, size_t pwdlen );

#if defined(POLARSSL_FS_IO)
/** \ingroup x509_module */
/**
 * \brief           Load and parse a private key
 *
 * \param ctx       key to be initialized
 * \param path      filename to read the private key from
 * \param password  password to decrypt the file (can be NULL)
 *
 * \return          0 if successful, or a specific PK or PEM error code
 */
int pk_parse_keyfile( pk_context *ctx,
                      const char *path, const char *password );
#endif /* POLARSSL_FS_IO */

/** \ingroup x509_module */
/**
 * \brief           Parse a public key
 *
 * \param ctx       key to be initialized
 * \param key       input buffer
 * \param keylen    size of the buffer
 *
 * \return          0 if successful, or a specific PK or PEM error code
 */
int pk_parse_public_key( pk_context *ctx,
                         const unsigned char *key, size_t keylen );

#if defined(POLARSSL_FS_IO)
/** \ingroup x509_module */
/**
 * \brief           Load and parse a public key
 *
 * \param ctx       key to be initialized
 * \param path      filename to read the private key from
 *
 * \return          0 if successful, or a specific PK or PEM error code
 */
int pk_parse_public_keyfile( pk_context *ctx, const char *path );
#endif /* POLARSSL_FS_IO */

/**
 * \brief           Parse a SubjectPublicKeyInfo DER structure
 *
 * \param p         the position in the ASN.1 data
 * \param end       end of the buffer
 * \param pk        the key to fill
 *
 * \return          0 if successful, or a specific PK error code
 */
int pk_parse_get_pubkey( unsigned char **p, const unsigned char *end,
                         pk_context *pk );

461 462 463 464
#ifdef __cplusplus
}
#endif

465
#endif /* POLARSSL_PK_H */