SRP Protocol Design
SRP is the newest addition to a new class of strong authentication protocols that resist all the well-known passive and active attacks over the network. SRP borrows some elements from other key-exchange and identification protcols and adds some subtle modifications and refinements. The result is a protocol that preserves the strength and efficiency of the EKE family protocols while fixing some of their shortcomings.
The following is a description of SRP-6 and 6a, the latest versions of SRP:
N A large safe prime (N = 2q+1, where q is prime)
All arithmetic is done modulo N.
g A generator modulo N
k Multiplier parameter (k = H(N, g) in SRP-6a, k = 3 for legacy SRP-6)
s User's salt
I Username
p Cleartext Password
H() One-way hash function
^ (Modular) Exponentiation
u Random scrambling parameter
a,b Secret ephemeral values
A,B Public ephemeral values
x Private key (derived from p and s)
v Password verifier
The host stores passwords using the following formula:
x = H(s, p) (s is chosen randomly)
v = g^x (computes password verifier)
The host then keeps {I, s, v} in its password database. The authentication protocol itself goes as follows:
User -> Host: I, A = g^a (identifies self, a = random number)
Host -> User: s, B = kv + g^b (sends salt, b = random number)
Both: u = H(A, B)
User: x = H(s, p) (user enters password)
User: S = (B - kg^x) ^ (a + ux) (computes session key)
User: K = H(S)
Host: S = (Av^u) ^ b (computes session key)
Host: K = H(S)
Now the two parties have a shared, strong session key K. To complete authentication, they need to prove to each other that their keys match. One possible way:
User -> Host: M = H(H(N) xor H(g), H(I), s, A, B, K)
Host -> User: H(A, M, K)
The two parties also employ the following safeguards:
The user will abort if he receives B == 0 (mod N) or u == 0.
The host will abort if it detects that A == 0 (mod N).
The user must show his proof of K first. If the server detects that the user's proof is incorrect, it must abort without showing its own proof of K.
A paper describing this protocol is also available, as well as a conference paper describing an older version of the protocol.
SrpWorld.h
//////////////////////////////////////////////////////////////////////
// SrpRealm
//
// SrpRealm headers
//////////////////////////////////////////////////////////////////////
// copyright (c) 2005 team wsd
//
// 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., 59 temple place - suite 330, boston, ma 02111-1307, usa.
#ifndef SRPREALM_H
#define SRPREALM_H
#include "bigint.h"
#include
#include
#include
#include
void reverse(char *d, char *s, int l);
int toInt(char c);
void fromHex(char *d, char *s, int l);
void getOdd(char *d, char *s, int l);
void getEven(char *d, char *s, int l);
void merge(char *d, char *s1, char *s2, int l);
void xorMerge(char *d, char *s1, char *s2, int l);
void printBigInteger(BigInteger BN, char *name);
void printBytes(char* bytes, int l, char *name);
class SrpRealm
{
protected:
char b[32];
char v[32];
public:
char user[1024];
char BR[32];
char N[32];
char M1[20];
char M2[20];
char SS_Hash[40];
char salt[32];
void challange(const char *userName, char *passwd);
void proof(char *A);
int BigIntegerToBytes2(BigInteger src, unsigned char * dest, int destlen);
};
#endif
SrpWorld.cpp
//////////////////////////////////////////////////////////////////////
// SrpWorld
//
// SrpWorld stuff
//////////////////////////////////////////////////////////////////////
// copyright (c) 2005 team wsd
//
// 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., 59 temple place - suite 330, boston, ma 02111-1307, usa.
#include "SrpWorld.h"
void SrpWorld::decode( unsigned char *data )
{
if(firstRecv && encrypt)
{
unsigned char* K = (unsigned char*)SS_Hash;
for(int i = 0; i < a =" prevbyte;" prevbyte =" data[i];" firstrecv =" true;" k =" (unsigned" i =" 0;i" prevbyte2 =" data[i];" firstsent =" true;">
SrpRealm.h
//////////////////////////////////////////////////////////////////////
// SrpRealm
//
// SrpRealm headers
//////////////////////////////////////////////////////////////////////
// copyright (c) 2005 team wsd
//
// 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., 59 temple place - suite 330, boston, ma 02111-1307, usa.
#ifndef SRPREALM_H
#define SRPREALM_H
#include "bigint.h"
#include
#include
#include
#include
void reverse(char *d, char *s, int l);
int toInt(char c);
void fromHex(char *d, char *s, int l);
void getOdd(char *d, char *s, int l);
void getEven(char *d, char *s, int l);
void merge(char *d, char *s1, char *s2, int l);
void xorMerge(char *d, char *s1, char *s2, int l);
void printBigInteger(BigInteger BN, char *name);
void printBytes(char* bytes, int l, char *name);
class SrpRealm
{
protected:
char b[32];
char v[32];
public:
char user[1024];
char BR[32];
char N[32];
char M1[20];
char M2[20];
char SS_Hash[40];
char salt[32];
void challange(const char *userName, char *passwd);
void proof(char *A);
int BigIntegerToBytes2(BigInteger src, unsigned char * dest, int destlen);
};
#endif
SrpRealm.cpp
//////////////////////////////////////////////////////////////////////
// SrpRealm
//
// SrpRealm stuff
//////////////////////////////////////////////////////////////////////
// copyright (c) 2005 team wsd
//
// 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., 59 temple place - suite 330, boston, ma 02111-1307, usa.
#include "bigint.h"
#include "SrpRealm.h"
#include
#include
#include
#include
#include
#include
#include
void reverse(char *d, char *s, int l)
{
int i;
for(i=0; i
bigint.h
/*
* Copyright (c) 1997-2004 The Stanford SRP Authentication Project
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
* THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* In addition, the following conditions apply:
*
* 1. Any software that incorporates the SRP authentication technology
* is requested to display the following acknowlegment:
* "This product uses the 'Secure Remote Password' cryptographic
* authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
*
* 2. Any software that incorporates all or part of the SRP distribution
* itself must display the following acknowledgment:
* "This product includes software developed by Tom Wu and Eugene
* Jhong for the SRP Distribution (http://srp.stanford.edu/)."
*
* 3. Redistributions in source or binary form must retain an intact copy
* of this copyright notice and list of conditions.
*/
#ifndef SRP_BIGINT_H
#define SRP_BIGINT_H
#define _WINSOCKAPI_
#ifdef __cplusplus
extern "C" {
#endif
/* BigInteger abstraction API */
#define _TYPE(a) a
#define P(x) x
#define OPENSSL 1
#define OPENSSL_ENGINE 1
#ifdef OPENSSL
#include "opensslv.h"
#include "bn.h"
typedef BIGNUM * BigInteger;
typedef BN_CTX * BigIntegerCtx;
typedef BN_MONT_CTX * BigIntegerModAccel;
# ifdef OPENSSL_ENGINE
#include "openssl/engine.h"
# endif /* OPENSSL_ENGINE */
typedef int (*modexp_meth)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *mctx);
#else
# error "no math library specified"
#endif
/*
* Some functions return a BigIntegerResult.
* Use BigIntegerOK to test for success.
*/
#define BIG_INTEGER_SUCCESS 0
#define BIG_INTEGER_ERROR -1
#define BigIntegerOK(v) ((v) == BIG_INTEGER_SUCCESS)
typedef int BigIntegerResult;
_TYPE( BigInteger ) BigIntegerFromInt P((unsigned int number));
_TYPE( BigInteger ) BigIntegerFromBytes P((const unsigned char * bytes,
int length));
#define BigIntegerByteLen(X) ((BigIntegerBitLen(X)+7)/8)
_TYPE( int ) BigIntegerToBytes P((BigInteger src,
unsigned char * dest, int destlen));
_TYPE( BigIntegerResult ) BigIntegerToHex P((BigInteger src,
char * dest, int destlen));
_TYPE( BigIntegerResult ) BigIntegerToString P((BigInteger src,
char * dest, int destlen,
unsigned int radix));
_TYPE( int ) BigIntegerBitLen P((BigInteger b));
_TYPE( int ) BigIntegerCmp P((BigInteger c1, BigInteger c2));
_TYPE( int ) BigIntegerCmpInt P((BigInteger c1, unsigned int c2));
_TYPE( BigIntegerResult ) BigIntegerLShift P((BigInteger result, BigInteger x,
unsigned int bits));
_TYPE( BigIntegerResult ) BigIntegerAdd P((BigInteger result,
BigInteger a1, BigInteger a2));
_TYPE( BigIntegerResult ) BigIntegerAddInt P((BigInteger result,
BigInteger a1, unsigned int a2));
_TYPE( BigIntegerResult ) BigIntegerSub P((BigInteger result,
BigInteger s1, BigInteger s2));
_TYPE( BigIntegerResult ) BigIntegerSubInt P((BigInteger result,
BigInteger s1, unsigned int s2));
/* For BigIntegerMul{,Int}: result != m1, m2 */
_TYPE( BigIntegerResult ) BigIntegerMul P((BigInteger result, BigInteger m1,
BigInteger m2, BigIntegerCtx ctx));
_TYPE( BigIntegerResult ) BigIntegerMulInt P((BigInteger result,
BigInteger m1, unsigned int m2,
BigIntegerCtx ctx));
_TYPE( BigIntegerResult ) BigIntegerDivInt P((BigInteger result,
BigInteger d, unsigned int m,
BigIntegerCtx ctx));
_TYPE( BigIntegerResult ) BigIntegerMod P((BigInteger result, BigInteger d,
BigInteger m, BigIntegerCtx ctx));
_TYPE( unsigned int ) BigIntegerModInt P((BigInteger d, unsigned int m,
BigIntegerCtx ctx));
_TYPE( BigIntegerResult ) BigIntegerModMul P((BigInteger result,
BigInteger m1, BigInteger m2,
BigInteger m, BigIntegerCtx ctx));
_TYPE( BigIntegerResult ) BigIntegerModExp P((BigInteger result,
BigInteger base, BigInteger expt,
BigInteger modulus,
BigIntegerCtx ctx,
BigIntegerModAccel accel));
_TYPE( int ) BigIntegerCheckPrime P((BigInteger n, BigIntegerCtx ctx));
_TYPE( BigIntegerResult ) BigIntegerFree P((BigInteger b));
_TYPE( BigIntegerResult ) BigIntegerClearFree P((BigInteger b));
_TYPE( BigIntegerCtx ) BigIntegerCtxNew();
_TYPE( BigIntegerResult ) BigIntegerCtxFree P((BigIntegerCtx ctx));
_TYPE( BigIntegerModAccel ) BigIntegerModAccelNew P((BigInteger m,
BigIntegerCtx ctx));
_TYPE( BigIntegerResult ) BigIntegerModAccelFree P((BigIntegerModAccel accel));
_TYPE( BigIntegerResult ) BigIntegerInitialize();
_TYPE( BigIntegerResult ) BigIntegerFinalize();
_TYPE( BigIntegerResult ) BigIntegerUseEngine P((const char * engine));
_TYPE( BigIntegerResult ) BigIntegerReleaseEngine();
#ifdef __cplusplus
}
#endif
#endif /* SRP_BIGINT_H */
bigint.c
/*
* Copyright (c) 1997-2004 The Stanford SRP Authentication Project
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
* THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* In addition, the following conditions apply:
*
* 1. Any software that incorporates the SRP authentication technology
* is requested to display the following acknowlegment:
* "This product uses the 'Secure Remote Password' cryptographic
* authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
*
* 2. Any software that incorporates all or part of the SRP distribution
* itself must display the following acknowledgment:
* "This product includes software developed by Tom Wu and Eugene
* Jhong for the SRP Distribution (http://srp.stanford.edu/)."
*
* 3. Redistributions in source or binary form must retain an intact copy
* of this copyright notice and list of conditions.
*/
#include
#include
#include
#include "bigint.h"
/* Math library interface stubs */
#ifdef OPENSSL
# ifdef OPENSSL_ENGINE
static ENGINE * default_engine = NULL;
# endif /* OPENSSL_ENGINE */
static modexp_meth default_modexp = NULL;
#endif
BigInteger BigIntegerFromInt(unsigned int n)
{
#ifdef OPENSSL
BIGNUM * a = BN_new();
if(a)
BN_set_word(a, n);
return a;
#endif
}
BigInteger BigIntegerFromBytes(const unsigned char * bytes, int length)
{
#ifdef OPENSSL
BIGNUM * a = BN_new();
BN_bin2bn(bytes, length, a);
return a;
#endif
}
int BigIntegerToBytes(BigInteger src, unsigned char * dest, int destlen)
{
#ifdef OPENSSL
return BN_bn2bin(src, dest);
#endif
}
BigIntegerResult BigIntegerToHex(BigInteger src, char * dest, int destlen)
{
#ifdef OPENSSL
strcpy(dest, BN_bn2hex(src));
#endif
return BIG_INTEGER_SUCCESS;
}
static char b64table[] =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
BigIntegerResult BigIntegerToString(BigInteger src, char * dest, int destlen, unsigned int radix)
{
BigInteger t = BigIntegerFromInt(0);
char * p = dest;
char c;
*p++ = b64table[BigIntegerModInt(src, radix, NULL)];
BigIntegerDivInt(t, src, radix, NULL);
while(BigIntegerCmpInt(t, 0) > 0) {
*p++ = b64table[BigIntegerModInt(t, radix, NULL)];
BigIntegerDivInt(t, t, radix, NULL);
}
BigIntegerFree(t);
*p-- = '\0';
/* reverse the string */
while(p > dest) {
c = *p;
*p-- = *dest;
*dest++ = c;
}
return BIG_INTEGER_SUCCESS;
}
int BigIntegerBitLen(BigInteger b)
{
#ifdef OPENSSL
return BN_num_bits(b);
#endif
}
int BigIntegerCmp(BigInteger c1, BigInteger c2)
{
#ifdef OPENSSL
return BN_cmp(c1, c2);
#endif
}
int BigIntegerCmpInt(BigInteger c1, unsigned int c2)
{
#ifdef OPENSSL
if(c1->top > 1)
return 1;
else if(c1->top <>d[0] - c2;
#endif
}
BigIntegerResult BigIntegerLShift(BigInteger result, BigInteger x, unsigned int bits)
{
#ifdef OPENSSL
BN_lshift(result, x, bits);
#endif
return BIG_INTEGER_SUCCESS;
}
BigIntegerResult BigIntegerAdd(BigInteger result, BigInteger a1, BigInteger a2)
{
#ifdef OPENSSL
BN_add(result, a1, a2);
#endif
return BIG_INTEGER_SUCCESS;
}
BigIntegerResult BigIntegerAddInt(BigInteger result, BigInteger a1, unsigned int a2)
{
#ifdef OPENSSL
if(result != a1)
BN_copy(result, a1);
BN_add_word(result, a2);
#endif
return BIG_INTEGER_SUCCESS;
}
BigIntegerResult BigIntegerSub(BigInteger result, BigInteger s1, BigInteger s2)
{
#ifdef OPENSSL
BN_sub(result, s1, s2);
#endif
return BIG_INTEGER_SUCCESS;
}
BigIntegerResult BigIntegerSubInt(BigInteger result, BigInteger s1, unsigned int s2)
{
#ifdef OPENSSL
if(result != s1)
BN_copy(result, s1);
BN_sub_word(result, s2);
#endif
return BIG_INTEGER_SUCCESS;
}
BigIntegerResult BigIntegerMul(BigInteger result, BigInteger m1, BigInteger m2, BigIntegerCtx c)
{
#ifdef OPENSSL
BN_CTX * ctx = NULL;
if(c == NULL)
c = ctx = BN_CTX_new();
BN_mul(result, m1, m2, c);
if(ctx)
BN_CTX_free(ctx);
#endif
return BIG_INTEGER_SUCCESS;
}
BigIntegerResult BigIntegerMulInt(BigInteger result, BigInteger m1, unsigned int m2, BigIntegerCtx c)
{
#ifdef OPENSSL
if(result != m1)
BN_copy(result, m1);
BN_mul_word(result, m2);
#endif
return BIG_INTEGER_SUCCESS;
}
BigIntegerResult BigIntegerDivInt(BigInteger result, BigInteger d, unsigned int m, BigIntegerCtx c)
{
#ifdef OPENSSL
if(result != d)
BN_copy(result, d);
BN_div_word(result, m);
#endif
return BIG_INTEGER_SUCCESS;
}
BigIntegerResult BigIntegerMod(BigInteger result, BigInteger d, BigInteger m, BigIntegerCtx c)
{
#ifdef OPENSSL
BN_CTX * ctx = NULL;
if(c == NULL)
c = ctx = BN_CTX_new();
BN_mod(result, d, m, c);
if(ctx)
BN_CTX_free(ctx);
#endif
return BIG_INTEGER_SUCCESS;
}
unsigned int BigIntegerModInt(BigInteger d, unsigned int m, BigIntegerCtx c)
{
#ifdef OPENSSL
return BN_mod_word(d, m);
#endif
}
BigIntegerResult BigIntegerModMul(BigInteger r, BigInteger m1, BigInteger m2, BigInteger modulus, BigIntegerCtx c)
{
#ifdef OPENSSL
BN_CTX * ctx = NULL;
if(c == NULL)
c = ctx = BN_CTX_new();
BN_mod_mul(r, m1, m2, modulus, c);
if(ctx)
BN_CTX_free(ctx);
#endif
return BIG_INTEGER_SUCCESS;
}
BigIntegerResult BigIntegerModExp(BigInteger r, BigInteger b, BigInteger e, BigInteger m, BigIntegerCtx c, BigIntegerModAccel a)
{
#ifdef OPENSSL
BN_CTX * ctx = NULL;
if(c == NULL)
c = ctx = BN_CTX_new();
if(default_modexp) {
(*default_modexp)(r, b, e, m, c, a);
}
else if(a == NULL) {
BN_mod_exp(r, b, e, m, c);
}
# if OPENSSL_VERSION_NUMBER >= 0x00906000
else if(b->top == 1) { /* 0.9.6 and above has mont_word optimization */
BN_ULONG B = b->d[0];
BN_mod_exp_mont_word(r, B, e, m, c, a);
}
# endif
else
BN_mod_exp_mont(r, b, e, m, c, a);
if(ctx)
BN_CTX_free(ctx);
#endif
return BIG_INTEGER_SUCCESS;
}
int BigIntegerCheckPrime(BigInteger n, BigIntegerCtx c)
{
#ifdef OPENSSL
int rv;
BN_CTX * ctx = NULL;
if(c == NULL)
c = ctx = BN_CTX_new();
rv = BN_is_prime(n, 25, NULL, c, NULL);
if(ctx)
BN_CTX_free(ctx);
return rv;
#endif
}
BigIntegerResult BigIntegerFree(BigInteger b)
{
#ifdef OPENSSL
BN_free(b);
#endif
return BIG_INTEGER_SUCCESS;
}
BigIntegerResult BigIntegerClearFree(BigInteger b)
{
#ifdef OPENSSL
BN_clear_free(b);
#endif
return BIG_INTEGER_SUCCESS;
}
BigIntegerCtx BigIntegerCtxNew()
{
#ifdef OPENSSL
return BN_CTX_new();
#else
return NULL;
#endif
}
BigIntegerResult BigIntegerCtxFree(BigIntegerCtx ctx)
{
#ifdef OPENSSL
if(ctx)
BN_CTX_free(ctx);
#endif
return BIG_INTEGER_SUCCESS;
}
BigIntegerModAccel BigIntegerModAccelNew(BigInteger m, BigIntegerCtx c)
{
#ifdef OPENSSL
BN_CTX * ctx = NULL;
BN_MONT_CTX * mctx;
if(default_modexp)
return NULL;
if(c == NULL)
c = ctx = BN_CTX_new();
mctx = BN_MONT_CTX_new();
BN_MONT_CTX_set(mctx, m, c);
if(ctx)
BN_CTX_free(ctx);
return mctx;
#else
return NULL;
#endif
}
BigIntegerResult BigIntegerModAccelFree(BigIntegerModAccel accel)
{
#ifdef OPENSSL
if(accel)
BN_MONT_CTX_free(accel);
#endif
return BIG_INTEGER_SUCCESS;
}
BigIntegerResult BigIntegerInitialize()
{
#if OPENSSL_VERSION_NUMBER >= 0x00907000
ENGINE_load_builtin_engines();
#endif
return BIG_INTEGER_SUCCESS;
}
BigIntegerResult BigIntegerFinalize()
{
return BigIntegerReleaseEngine();
}
BigIntegerResult BigIntegerUseEngine(const char * engine)
{
#if defined(OPENSSL) && defined(OPENSSL_ENGINE)
ENGINE * e = ENGINE_by_id(engine);
if(e) {
if(ENGINE_init(e) > 0) {
# if OPENSSL_VERSION_NUMBER >= 0x00907000
/* 0.9.7 loses the BN_mod_exp method. Pity. */
const RSA_METHOD * rsa = ENGINE_get_RSA(e);
if(rsa)
default_modexp = (modexp_meth)rsa->bn_mod_exp;
# else
default_modexp = (modexp_meth)ENGINE_get_BN_mod_exp(e);
# endif
BigIntegerReleaseEngine();
default_engine = e;
return BIG_INTEGER_SUCCESS;
}
else
ENGINE_free(e);
}
#endif
return BIG_INTEGER_ERROR;
}
BigIntegerResult BigIntegerReleaseEngine()
{
#if defined(OPENSSL) && defined(OPENSSL_ENGINE)
if(default_engine) {
ENGINE_finish(default_engine);
ENGINE_free(default_engine);
default_engine = NULL;
default_modexp = NULL;
}
#endif
return BIG_INTEGER_SUCCESS;
}