├── sample ├── Makefile.unix ├── Makefile.win ├── test_verify.c └── test_sign.c ├── Makefile.win ├── Makefile.mac ├── Makefile.unix ├── README ├── base64.h ├── sha1.h ├── sha2.h ├── base64.c ├── pdkim.h ├── sha1.c ├── sha2.c ├── rsa.h ├── bignum.h ├── LICENSE ├── rsa.c └── bn_mul.h /sample/Makefile.unix: -------------------------------------------------------------------------------- 1 | MAJOR_VERSION=1 2 | CFLAGS= 3 | OFLAGS= 4 | 5 | all: 6 | $(CC) $(CFLAGS) $(OFLAGS) -o test_verify test_verify.c -lpdkim$(MAJOR_VERSION) 7 | $(CC) $(CFLAGS) $(OFLAGS) -o test_sign test_sign.c -lpdkim$(MAJOR_VERSION) 8 | 9 | test: all 10 | ./test_sign | ./test_verify 11 | 12 | clean: 13 | rm -f test_verify test_sign 14 | -------------------------------------------------------------------------------- /sample/Makefile.win: -------------------------------------------------------------------------------- 1 | VERSION_MAJOR=1 2 | CFLAGS=/I.. /DWINDOWS 3 | OFLAGS= 4 | 5 | all: 6 | $(CC) $(CFLAGS) $(OFLAGS) test_verify.c /link ..\pdkim$(VERSION_MAJOR)-static.lib 7 | $(CC) $(CFLAGS) $(OFLAGS) test_sign.c /link ..\pdkim$(VERSION_MAJOR)-static.lib 8 | 9 | test: all 10 | test_sign.exe | test_verify.exe 11 | 12 | clean: 13 | del /Q *.exp *.lib *.obj *.exe 14 | -------------------------------------------------------------------------------- /Makefile.win: -------------------------------------------------------------------------------- 1 | VERSION_MAJOR=1 2 | VERSION_MINOR=0 3 | LIBNAME=pdkim 4 | 5 | CFLAGS=-DWINDOWS 6 | OFLAGS=-Os 7 | 8 | OBJS=sha1.obj sha2.obj base64.obj rsa.obj bignum.obj pdkim.obj 9 | 10 | .SILENT: 11 | 12 | all: static shared 13 | 14 | static: $(OBJS) 15 | lib /out:$(LIBNAME)$(VERSION_MAJOR)-static.lib $(OBJS) 16 | 17 | shared: static 18 | link /DLL /OUT:$(LIBNAME)$(VERSION_MAJOR).dll $(OBJS) 19 | 20 | .c.obj: 21 | $(CC) $(CFLAGS) $(OFLAGS) -c $< 22 | 23 | clean: 24 | del /Q *.obj *.exp *.lib pdkim$(VERSION_MAJOR).dll 25 | -------------------------------------------------------------------------------- /Makefile.mac: -------------------------------------------------------------------------------- 1 | PREFIX=/usr 2 | VERSION_MAJOR=1 3 | VERSION_MINOR=0 4 | LIBNAME=libpdkim 5 | 6 | CFLAGS=-Wall -D_FILE_OFFSET_BITS=64 -fPIC -arch i386 -arch x86_64 7 | OFLAGS=-Os 8 | 9 | OBJS=sha1.o sha2.o base64.o rsa.o bignum.o pdkim.o 10 | 11 | .SILENT: 12 | 13 | all: static shared 14 | 15 | install: all 16 | echo "Installing lib to $(PREFIX)/lib/, header to $(PREFIX)/include/" 17 | cp -v $(LIBNAME)$(VERSION_MAJOR).a $(PREFIX)/lib/ 18 | cp -v $(LIBNAME)$(VERSION_MAJOR).dylib $(PREFIX)/lib/ 19 | cp -v pdkim.h $(PREFIX)/include/pdkim$(VERSION_MAJOR).h 20 | 21 | uninstall: clean 22 | echo "Removing lib from $(PREFIX)/lib/, header from $(PREFIX)/include/" 23 | rm -f $(PREFIX)/lib/$(LIBNAME)$(VERSION_MAJOR).a 24 | rm -f $(PREFIX)/lib/$(LIBNAME)$(VERSION_MAJOR).so.* 25 | rm -f $(PREFIX)/include/pdkim.h 26 | 27 | static: $(OBJS) 28 | echo "AR $(LIBNAME)$(VERSION_MAJOR).a" 29 | rm -f $(LIBNAME)$(VERSION_MAJOR).a 30 | ar r $(LIBNAME)$(VERSION_MAJOR).a $(OBJS) 31 | echo "RL $(LIBNAME)$(VERSION_MAJOR).a" 32 | ranlib $(LIBNAME)$(VERSION_MAJOR).a 33 | 34 | shared: static 35 | echo "LD $(LIBNAME)$(VERSION_MAJOR).so.$(VERSION_MINOR)" 36 | $(CC) ${CFLAGS} -dynamiclib -o $(LIBNAME)$(VERSION_MAJOR).dylib $(OBJS) 37 | 38 | .c.o: 39 | echo "CC $<" 40 | $(CC) $(CFLAGS) $(OFLAGS) -c $< 41 | 42 | clean: 43 | rm -f *.o libpdkim$(VERSION_MAJOR).* 44 | -------------------------------------------------------------------------------- /Makefile.unix: -------------------------------------------------------------------------------- 1 | PREFIX=/usr 2 | VERSION_MAJOR=1 3 | VERSION_MINOR=0 4 | LIBNAME=libpdkim 5 | 6 | CFLAGS=-Wall -D_FILE_OFFSET_BITS=64 -fPIC 7 | OFLAGS=-Os 8 | 9 | OBJS=sha1.o sha2.o base64.o rsa.o bignum.o pdkim.o 10 | 11 | .SILENT: 12 | 13 | all: static shared 14 | 15 | install: all 16 | echo "Installing lib to $(PREFIX)/lib/, header to $(PREFIX)/include/" 17 | cp -v $(LIBNAME)$(VERSION_MAJOR).a $(PREFIX)/lib/ 18 | cp -v $(LIBNAME)$(VERSION_MAJOR).so.$(VERSION_MINOR) $(PREFIX)/lib/ 19 | cp -v pdkim.h $(PREFIX)/include/pdkim$(VERSION_MAJOR).h 20 | echo "LDCONFIG" 21 | ldconfig 22 | 23 | uninstall: clean 24 | echo "Removing lib from $(PREFIX)/lib/, header from $(PREFIX)/include/" 25 | rm -f $(PREFIX)/lib/$(LIBNAME)$(VERSION_MAJOR).a 26 | rm -f $(PREFIX)/lib/$(LIBNAME)$(VERSION_MAJOR).so.* 27 | rm -f $(PREFIX)/include/pdkim.h 28 | 29 | static: $(OBJS) 30 | echo "AR $(LIBNAME)$(VERSION_MAJOR).a" 31 | ar r $(LIBNAME)$(VERSION_MAJOR).a $(OBJS) 32 | echo "RL $(LIBNAME)$(VERSION_MAJOR).a" 33 | ranlib $(LIBNAME)$(VERSION_MAJOR).a 34 | 35 | shared: static 36 | echo "LD $(LIBNAME)$(VERSION_MAJOR).so.$(VERSION_MINOR)" 37 | $(CC) -shared -Wl,-soname,$(LIBNAME)$(VERSION_MAJOR).so -o $(LIBNAME)$(VERSION_MAJOR).so.$(VERSION_MINOR) $(OBJS) 38 | strip --strip-unneeded $(LIBNAME)$(VERSION_MAJOR).so.$(VERSION_MINOR) 39 | 40 | .c.o: 41 | echo "CC $<" 42 | $(CC) $(CFLAGS) $(OFLAGS) -c $< 43 | 44 | clean: 45 | rm -f *.o libpdkim$(VERSION_MAJOR).* 46 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | PDKIM - a RFC4871 (DKIM) implementation 2 | http://duncanthrax.net/pdkim/ 3 | Copyright (C) 2009 Tom Kistner 4 | 5 | Includes code from the PolarSSL project. 6 | http://polarssl.org 7 | Copyright (C) 2009 Paul Bakker 8 | Copyright (C) 2006-2008 Christophe Devine 9 | 10 | 11 | 12 | Building on Unix 13 | ---------------- 14 | 15 | 1) Review Makefile.unix 16 | 17 | 2) # make -f Makefile.unix install 18 | 19 | This will install static/dynamic libs and the header file, 20 | which is a prerequisite for running a test: 21 | 22 | 3) (OPTIONAL) 23 | # cd sample; make -f Makefile.unix test 24 | 25 | Please note that libs and header carry the major version number in 26 | their names, i.e. "pdkim1.h" or "pkdim1.so.0". 27 | 28 | 29 | 30 | Building on Windows 31 | ------------------- 32 | 33 | Using Visual C/C++ compiler: 34 | 35 | 1) Open a cmd.exe shell. 36 | 37 | 2) Run vcvarsall.bat inside that shell. Usually this can be 38 | found in the \VC subdir of your VC++ installation. 39 | 40 | 3) # nmake /f Makefile.win 41 | 42 | This will create a static library "pdkim1-static.lib", as well 43 | as a dynamic pdkim1.lib/pdkim1.dll file pair. The header is 44 | copied to pdkim1.h. These are no installation locations. Please 45 | copy the respective files to a location of your choice (or leave 46 | them where they are ...). 47 | 48 | 49 | 50 | API Documentation 51 | ----------------- 52 | 53 | For signing, read sample/test_sign.c. For verification, read 54 | sample/test_verify.c 55 | 56 | Both have extensive comments covering the API calls. They will 57 | direct you to read the pdkim1.h file that covers the signature 58 | structure. 59 | 60 | 61 | -------------------------------------------------------------------------------- /base64.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file base64.h 3 | * 4 | * Copyright (C) 2006-2010, Brainspark B.V. 5 | * 6 | * This file is part of PolarSSL (http://www.polarssl.org) 7 | * Lead Maintainer: Paul Bakker 8 | * 9 | * All rights reserved. 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; if not, write to the Free Software Foundation, Inc., 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 24 | */ 25 | #ifndef POLARSSL_BASE64_H 26 | #define POLARSSL_BASE64_H 27 | 28 | #define POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL 0x0010 29 | #define POLARSSL_ERR_BASE64_INVALID_CHARACTER 0x0012 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | /** 36 | * \brief Encode a buffer into base64 format 37 | * 38 | * \param dst destination buffer 39 | * \param dlen size of the buffer 40 | * \param src source buffer 41 | * \param slen amount of data to be encoded 42 | * 43 | * \return 0 if successful, or POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL. 44 | * *dlen is always updated to reflect the amount 45 | * of data that has (or would have) been written. 46 | * 47 | * \note Call this function with *dlen = 0 to obtain the 48 | * required buffer size in *dlen 49 | */ 50 | int base64_encode( unsigned char *dst, int *dlen, 51 | const unsigned char *src, int slen ); 52 | 53 | /** 54 | * \brief Decode a base64-formatted buffer 55 | * 56 | * \param dst destination buffer 57 | * \param dlen size of the buffer 58 | * \param src source buffer 59 | * \param slen amount of data to be decoded 60 | * 61 | * \return 0 if successful, POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL, or 62 | * POLARSSL_ERR_BASE64_INVALID_DATA if the input data is not 63 | * correct. *dlen is always updated to reflect the amount 64 | * of data that has (or would have) been written. 65 | * 66 | * \note Call this function with *dlen = 0 to obtain the 67 | * required buffer size in *dlen 68 | */ 69 | int base64_decode( unsigned char *dst, int *dlen, 70 | const unsigned char *src, int slen ); 71 | 72 | #ifdef __cplusplus 73 | } 74 | #endif 75 | 76 | #endif /* base64.h */ 77 | -------------------------------------------------------------------------------- /sha1.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file sha1.h 3 | * 4 | * Copyright (C) 2006-2010, Brainspark B.V. 5 | * 6 | * This file is part of PolarSSL (http://www.polarssl.org) 7 | * Lead Maintainer: Paul Bakker 8 | * 9 | * All rights reserved. 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; if not, write to the Free Software Foundation, Inc., 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 24 | */ 25 | #ifndef POLARSSL_SHA1_H 26 | #define POLARSSL_SHA1_H 27 | 28 | /** 29 | * \brief SHA-1 context structure 30 | */ 31 | #ifndef HAVE_SHA1_CONTEXT 32 | #define HAVE_SHA1_CONTEXT 33 | typedef struct sha1_context sha1_context; 34 | #endif 35 | 36 | struct sha1_context 37 | { 38 | unsigned long total[2]; /*!< number of bytes processed */ 39 | unsigned long state[5]; /*!< intermediate digest state */ 40 | unsigned char buffer[64]; /*!< data block being processed */ 41 | 42 | unsigned char ipad[64]; /*!< HMAC: inner padding */ 43 | unsigned char opad[64]; /*!< HMAC: outer padding */ 44 | }; 45 | 46 | #ifdef __cplusplus 47 | extern "C" { 48 | #endif 49 | 50 | /** 51 | * \brief SHA-1 context setup 52 | * 53 | * \param ctx context to be initialized 54 | */ 55 | void sha1_starts( sha1_context *ctx ); 56 | 57 | /** 58 | * \brief SHA-1 process buffer 59 | * 60 | * \param ctx SHA-1 context 61 | * \param input buffer holding the data 62 | * \param ilen length of the input data 63 | */ 64 | void sha1_update( sha1_context *ctx, const unsigned char *input, int ilen ); 65 | 66 | /** 67 | * \brief SHA-1 final digest 68 | * 69 | * \param ctx SHA-1 context 70 | * \param output SHA-1 checksum result 71 | */ 72 | void sha1_finish( sha1_context *ctx, unsigned char output[20] ); 73 | 74 | /** 75 | * \brief Output = SHA-1( input buffer ) 76 | * 77 | * \param input buffer holding the data 78 | * \param ilen length of the input data 79 | * \param output SHA-1 checksum result 80 | */ 81 | void sha1( const unsigned char *input, int ilen, unsigned char output[20] ); 82 | 83 | /** 84 | * \brief Output = SHA-1( file contents ) 85 | * 86 | * \param path input file name 87 | * \param output SHA-1 checksum result 88 | * 89 | * \return 0 if successful, 1 if fopen failed, 90 | * or 2 if fread failed 91 | */ 92 | int sha1_file( const char *path, unsigned char output[20] ); 93 | 94 | /** 95 | * \brief SHA-1 HMAC context setup 96 | * 97 | * \param ctx HMAC context to be initialized 98 | * \param key HMAC secret key 99 | * \param keylen length of the HMAC key 100 | */ 101 | void sha1_hmac_starts( sha1_context *ctx, const unsigned char *key, int keylen ); 102 | 103 | /** 104 | * \brief SHA-1 HMAC process buffer 105 | * 106 | * \param ctx HMAC context 107 | * \param input buffer holding the data 108 | * \param ilen length of the input data 109 | */ 110 | void sha1_hmac_update( sha1_context *ctx, const unsigned char *input, int ilen ); 111 | 112 | /** 113 | * \brief SHA-1 HMAC final digest 114 | * 115 | * \param ctx HMAC context 116 | * \param output SHA-1 HMAC checksum result 117 | */ 118 | void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] ); 119 | 120 | /** 121 | * \brief SHA-1 HMAC context reset 122 | * 123 | * \param ctx HMAC context to be reset 124 | */ 125 | void sha1_hmac_reset( sha1_context *ctx ); 126 | 127 | /** 128 | * \brief Output = HMAC-SHA-1( hmac key, input buffer ) 129 | * 130 | * \param key HMAC secret key 131 | * \param keylen length of the HMAC key 132 | * \param input buffer holding the data 133 | * \param ilen length of the input data 134 | * \param output HMAC-SHA-1 result 135 | */ 136 | void sha1_hmac( const unsigned char *key, int keylen, 137 | const unsigned char *input, int ilen, 138 | unsigned char output[20] ); 139 | 140 | #ifdef __cplusplus 141 | } 142 | #endif 143 | 144 | #endif /* sha1.h */ 145 | -------------------------------------------------------------------------------- /sha2.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file sha2.h 3 | * 4 | * Copyright (C) 2006-2010, Brainspark B.V. 5 | * 6 | * This file is part of PolarSSL (http://www.polarssl.org) 7 | * Lead Maintainer: Paul Bakker 8 | * 9 | * All rights reserved. 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; if not, write to the Free Software Foundation, Inc., 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 24 | */ 25 | #ifndef POLARSSL_SHA2_H 26 | #define POLARSSL_SHA2_H 27 | 28 | /** 29 | * \brief SHA-256 context structure 30 | */ 31 | #ifndef HAVE_SHA2_CONTEXT 32 | #define HAVE_SHA2_CONTEXT 33 | typedef struct sha2_context sha2_context; 34 | #endif 35 | 36 | struct sha2_context 37 | { 38 | unsigned long total[2]; /*!< number of bytes processed */ 39 | unsigned long state[8]; /*!< intermediate digest state */ 40 | unsigned char buffer[64]; /*!< data block being processed */ 41 | 42 | unsigned char ipad[64]; /*!< HMAC: inner padding */ 43 | unsigned char opad[64]; /*!< HMAC: outer padding */ 44 | int is224; /*!< 0 => SHA-256, else SHA-224 */ 45 | }; 46 | 47 | #ifdef __cplusplus 48 | extern "C" { 49 | #endif 50 | 51 | /** 52 | * \brief SHA-256 context setup 53 | * 54 | * \param ctx context to be initialized 55 | * \param is224 0 = use SHA256, 1 = use SHA224 56 | */ 57 | void sha2_starts( sha2_context *ctx, int is224 ); 58 | 59 | /** 60 | * \brief SHA-256 process buffer 61 | * 62 | * \param ctx SHA-256 context 63 | * \param input buffer holding the data 64 | * \param ilen length of the input data 65 | */ 66 | void sha2_update( sha2_context *ctx, const unsigned char *input, int ilen ); 67 | 68 | /** 69 | * \brief SHA-256 final digest 70 | * 71 | * \param ctx SHA-256 context 72 | * \param output SHA-224/256 checksum result 73 | */ 74 | void sha2_finish( sha2_context *ctx, unsigned char output[32] ); 75 | 76 | /** 77 | * \brief Output = SHA-256( input buffer ) 78 | * 79 | * \param input buffer holding the data 80 | * \param ilen length of the input data 81 | * \param output SHA-224/256 checksum result 82 | * \param is224 0 = use SHA256, 1 = use SHA224 83 | */ 84 | void sha2( const unsigned char *input, int ilen, 85 | unsigned char output[32], int is224 ); 86 | 87 | /** 88 | * \brief Output = SHA-256( file contents ) 89 | * 90 | * \param path input file name 91 | * \param output SHA-224/256 checksum result 92 | * \param is224 0 = use SHA256, 1 = use SHA224 93 | * 94 | * \return 0 if successful, 1 if fopen failed, 95 | * or 2 if fread failed 96 | */ 97 | int sha2_file( const char *path, unsigned char output[32], int is224 ); 98 | 99 | /** 100 | * \brief SHA-256 HMAC context setup 101 | * 102 | * \param ctx HMAC context to be initialized 103 | * \param key HMAC secret key 104 | * \param keylen length of the HMAC key 105 | * \param is224 0 = use SHA256, 1 = use SHA224 106 | */ 107 | void sha2_hmac_starts( sha2_context *ctx, const unsigned char *key, int keylen, 108 | int is224 ); 109 | 110 | /** 111 | * \brief SHA-256 HMAC process buffer 112 | * 113 | * \param ctx HMAC context 114 | * \param input buffer holding the data 115 | * \param ilen length of the input data 116 | */ 117 | void sha2_hmac_update( sha2_context *ctx, const unsigned char *input, int ilen ); 118 | 119 | /** 120 | * \brief SHA-256 HMAC final digest 121 | * 122 | * \param ctx HMAC context 123 | * \param output SHA-224/256 HMAC checksum result 124 | */ 125 | void sha2_hmac_finish( sha2_context *ctx, unsigned char output[32] ); 126 | 127 | /** 128 | * \brief SHA-256 HMAC context reset 129 | * 130 | * \param ctx HMAC context to be reset 131 | */ 132 | void sha2_hmac_reset( sha2_context *ctx ); 133 | 134 | /** 135 | * \brief Output = HMAC-SHA-256( hmac key, input buffer ) 136 | * 137 | * \param key HMAC secret key 138 | * \param keylen length of the HMAC key 139 | * \param input buffer holding the data 140 | * \param ilen length of the input data 141 | * \param output HMAC-SHA-224/256 result 142 | * \param is224 0 = use SHA256, 1 = use SHA224 143 | */ 144 | void sha2_hmac( const unsigned char *key, int keylen, 145 | const unsigned char *input, int ilen, 146 | unsigned char output[32], int is224 ); 147 | 148 | #ifdef __cplusplus 149 | } 150 | #endif 151 | 152 | #endif /* sha2.h */ 153 | -------------------------------------------------------------------------------- /base64.c: -------------------------------------------------------------------------------- 1 | /* 2 | * RFC 1521 base64 encoding/decoding 3 | * 4 | * Copyright (C) 2006-2010, Brainspark B.V. 5 | * 6 | * This file is part of PolarSSL (http://www.polarssl.org) 7 | * Lead Maintainer: Paul Bakker 8 | * 9 | * All rights reserved. 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; if not, write to the Free Software Foundation, Inc., 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 24 | */ 25 | 26 | 27 | #include "base64.h" 28 | 29 | static const unsigned char base64_enc_map[64] = 30 | { 31 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 32 | 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 33 | 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 34 | 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 35 | 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 36 | 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', 37 | '8', '9', '+', '/' 38 | }; 39 | 40 | static const unsigned char base64_dec_map[128] = 41 | { 42 | 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 43 | 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 44 | 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 45 | 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 46 | 127, 127, 127, 62, 127, 127, 127, 63, 52, 53, 47 | 54, 55, 56, 57, 58, 59, 60, 61, 127, 127, 48 | 127, 64, 127, 127, 127, 0, 1, 2, 3, 4, 49 | 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 50 | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 51 | 25, 127, 127, 127, 127, 127, 127, 26, 27, 28, 52 | 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 53 | 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 54 | 49, 50, 51, 127, 127, 127, 127, 127 55 | }; 56 | 57 | /* 58 | * Encode a buffer into base64 format 59 | */ 60 | int base64_encode( unsigned char *dst, int *dlen, 61 | const unsigned char *src, int slen ) 62 | { 63 | int i, n; 64 | int C1, C2, C3; 65 | unsigned char *p; 66 | 67 | if( slen == 0 ) 68 | return( 0 ); 69 | 70 | n = (slen << 3) / 6; 71 | 72 | switch( (slen << 3) - (n * 6) ) 73 | { 74 | case 2: n += 3; break; 75 | case 4: n += 2; break; 76 | default: break; 77 | } 78 | 79 | if( *dlen < n + 1 ) 80 | { 81 | *dlen = n + 1; 82 | return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL ); 83 | } 84 | 85 | n = (slen / 3) * 3; 86 | 87 | for( i = 0, p = dst; i < n; i += 3 ) 88 | { 89 | C1 = *src++; 90 | C2 = *src++; 91 | C3 = *src++; 92 | 93 | *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; 94 | *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; 95 | *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F]; 96 | *p++ = base64_enc_map[C3 & 0x3F]; 97 | } 98 | 99 | if( i < slen ) 100 | { 101 | C1 = *src++; 102 | C2 = ((i + 1) < slen) ? *src++ : 0; 103 | 104 | *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; 105 | *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; 106 | 107 | if( (i + 1) < slen ) 108 | *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F]; 109 | else *p++ = '='; 110 | 111 | *p++ = '='; 112 | } 113 | 114 | *dlen = p - dst; 115 | *p = 0; 116 | 117 | return( 0 ); 118 | } 119 | 120 | /* 121 | * Decode a base64-formatted buffer 122 | */ 123 | int base64_decode( unsigned char *dst, int *dlen, 124 | const unsigned char *src, int slen ) 125 | { 126 | int i, j, n; 127 | unsigned long x; 128 | unsigned char *p; 129 | 130 | for( i = j = n = 0; i < slen; i++ ) 131 | { 132 | if( ( slen - i ) >= 2 && 133 | src[i] == '\r' && src[i + 1] == '\n' ) 134 | continue; 135 | 136 | if( src[i] == '\n' ) 137 | continue; 138 | 139 | if( src[i] == '=' && ++j > 2 ) 140 | return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); 141 | 142 | if( src[i] > 127 || base64_dec_map[src[i]] == 127 ) 143 | return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); 144 | 145 | if( base64_dec_map[src[i]] < 64 && j != 0 ) 146 | return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); 147 | 148 | n++; 149 | } 150 | 151 | if( n == 0 ) 152 | return( 0 ); 153 | 154 | n = ((n * 6) + 7) >> 3; 155 | 156 | if( *dlen < n ) 157 | { 158 | *dlen = n; 159 | return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL ); 160 | } 161 | 162 | for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ ) 163 | { 164 | if( *src == '\r' || *src == '\n' ) 165 | continue; 166 | 167 | j -= ( base64_dec_map[*src] == 64 ); 168 | x = (x << 6) | ( base64_dec_map[*src] & 0x3F ); 169 | 170 | if( ++n == 4 ) 171 | { 172 | n = 0; 173 | if( j > 0 ) *p++ = (unsigned char)( x >> 16 ); 174 | if( j > 1 ) *p++ = (unsigned char)( x >> 8 ); 175 | if( j > 2 ) *p++ = (unsigned char)( x ); 176 | } 177 | } 178 | 179 | *dlen = p - dst; 180 | 181 | return( 0 ); 182 | } 183 | 184 | -------------------------------------------------------------------------------- /sample/test_verify.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PDKIM - a RFC4871 (DKIM) implementation 3 | * 4 | * Verification test & sample code. 5 | * 6 | * Copyright (C) 2009 Tom Kistner 7 | * http://duncanthrax.net/pdkim/ 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | /* A DKIM public key record, as it usually resides in a DNS TXT record. */ 18 | char dns_txt_record[] = "v=DKIM1; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB"\ 19 | "gQC5+utIbbfbpssvW0TboF73Seos+1ijdPFGwc/z8Yu12cp"\ 20 | "jBvRb5/qRJd83XCySRs0QkK1zWx4soPffbtyJ9TU5mO76M2"\ 21 | "3lIuI5slJ4QLA0UznGxfHdfXpK9qRnmG6A4HRHC9B93pjTo"\ 22 | "6iBksRhIeSsTL94EbUJ625i0Lqg4i6NVQIDAQAB;"; 23 | 24 | /* This callback function is called by the PDKIM library to retrieve 25 | * DKIM public key records. A pointer to this function is passed to 26 | * the library with the pdkim_init_verify() call (see further below). 27 | * On success, this function must return 0 (PDKIM_OK). On failure, it 28 | * should return a non-0 value. 29 | * 30 | * char *name 31 | * The fully qualified name of the DNS TXT record to be 32 | * retrieved ("selector._domainkey.domain.example"). 33 | * 34 | * char *answer 35 | * Pointer to preallocated and zeroed memory of size 36 | * PDKIM_DNS_TXT_MAX_RECLEN. The function should copy the 37 | * retrieved DNS TXT record to that location. 38 | */ 39 | int query_dns_txt(char *name, char *answer) { 40 | /* This mockup function does not use DNS, but just returns 41 | a hardcoded record */ 42 | strcpy(answer,dns_txt_record); 43 | return PDKIM_OK; 44 | } 45 | 46 | /* This function retrieves a message on STDIN and verifies present 47 | * DKIM signatures. Due to the limitations of this sample code, this 48 | * only works for signatures created with the key in test_sign.c. 49 | * 50 | * Please note that this sample code skips on some error checking 51 | * and handling for the sake of clarity and brevity. 52 | */ 53 | #define MAX_LINE_LEN 1024 54 | int main(int argc, char *argv[]) { 55 | FILE *input; 56 | FILE *debug; 57 | char buffer[MAX_LINE_LEN]; 58 | 59 | pdkim_ctx *ctx; 60 | pdkim_signature *signatures; 61 | 62 | /* pdkim_ctx *pdkim_init_verify(int mode, 63 | * int(*)(char *, char *)) 64 | * 65 | * Initialize context for verification. 66 | * 67 | * int mode 68 | * PDKIM_INPUT_NORMAL or PDKIM_INPUT_SMTP. When SMTP 69 | * input is used, the lib will deflate double-dots at 70 | * the start of atline to a single dot, and it will 71 | * stop processing input when a line with and single 72 | * dot is received (Excess input will simply be ignored). 73 | * 74 | * int(*)(char *, char *) 75 | * Pointer to your DNS/TXT callback function. See 76 | * the query_dns_txt() stub above. The lib does not 77 | * include a DNS resolver, so you need to provide that 78 | * yourself. If you develop an application that deals 79 | * with email, you'll probably have something anyway. 80 | * 81 | * Returns: A pointer to a freshly allocated pdkim_ctx 82 | * context. 83 | */ 84 | ctx = pdkim_init_verify(PDKIM_INPUT_NORMAL, 85 | &query_dns_txt 86 | ); 87 | 88 | /* void pdkim_set_debug_stream(pdkim_ctx *ctx, 89 | * FILE *debug) 90 | * 91 | * Set up debugging stream. 92 | * 93 | * When PDKIM was compiled with DEBUG defined (which is the 94 | * recommended default), you can set up a stream where it 95 | * sends debug output to. In this example, we simply use 96 | * STDERR (fd 2) for that purpose. If you don't set a debug 97 | * stream, no debug output is generated. 98 | */ 99 | debug = fdopen(2,"a"); 100 | pdkim_set_debug_stream(ctx,debug); 101 | 102 | /* int pdkim_feed(pdkim_ctx *ctx, 103 | * char *data, 104 | * int data_len) 105 | * 106 | * (Repeatedly) feed data to the signing algorithm. The message 107 | * data MUST use CRLF line endings (like SMTP uses on the 108 | * wire). The data chunks do not need to be a "line" - you 109 | * can split chunks at arbitrary locations. 110 | * 111 | * char *data 112 | * Pointer to data to feed. Please note that despite 113 | * the example given below, this is not necessarily a 114 | * C string. 115 | * 116 | * int data_len 117 | * Length of data being fed, in bytes. 118 | * 119 | * Returns: 0 (PDKIM_OK) for success or a PDKIM_ERR_* constant 120 | */ 121 | input = fdopen(0,"r"); 122 | while (fgets(buffer, MAX_LINE_LEN, input)) { 123 | if (pdkim_feed(ctx,buffer,strlen(buffer)) != PDKIM_OK) { 124 | printf("pdkim_feed() error\n"); 125 | goto BAIL; 126 | } 127 | } 128 | 129 | /* int pdkim_feed_finish(pdkim_ctx *ctx, 130 | * pdkim_signature **signatures, 131 | * 132 | * Signal end-of-message and retrieve the signature block(s). 133 | * 134 | * pdkim_signature **signature 135 | * Pass in a pointer to a pdkim_signature pointer. 136 | * If the function returns PDKIM_OK, it will be set 137 | * up to point to (several chained) freshly allocated 138 | * pdkim_signature block(s). See pdkim.h for 139 | * documentation on what these blocks contain. 140 | * 141 | * Returns: 0 (PDKIM_OK) for success or a PDKIM_ERR_* constant 142 | */ 143 | if (pdkim_feed_finish(ctx,&signatures) == PDKIM_OK) { 144 | while (signatures != NULL) { 145 | printf("Signature from domain '%s': ",signatures->domain); 146 | switch(signatures->verify_status) { 147 | case PDKIM_VERIFY_NONE: printf("not verified\n"); break; 148 | case PDKIM_VERIFY_INVALID: printf("invalid\n"); break; 149 | case PDKIM_VERIFY_FAIL: printf("verification failed\n"); break; 150 | case PDKIM_VERIFY_PASS: printf("verification succeeded\n"); break; 151 | } 152 | /* Try next signature */ 153 | signatures = signatures->next; 154 | } 155 | } 156 | 157 | BAIL: 158 | /* void pdkim_free_ctx(pdkim_ctx *ctx) 159 | * 160 | * Free all allocated memory blocks referenced from 161 | * the context (including signature blocks), as well 162 | * as the context itself. 163 | */ 164 | pdkim_free_ctx(ctx); 165 | 166 | fclose(input); 167 | fclose(debug); 168 | } 169 | -------------------------------------------------------------------------------- /sample/test_sign.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PDKIM - a RFC4871 (DKIM) implementation 3 | * 4 | * Signing test & sample code. 5 | * 6 | * Copyright (C) 2009 Tom Kistner 7 | * http://duncanthrax.net/pdkim/ 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | #define RSA_PRIVKEY "-----BEGIN RSA PRIVATE KEY-----\n\ 18 | MIICXQIBAAKBgQC5+utIbbfbpssvW0TboF73Seos+1ijdPFGwc/z8Yu12cpjBvRb\n\ 19 | 5/qRJd83XCySRs0QkK1zWx4soPffbtyJ9TU5mO76M23lIuI5slJ4QLA0UznGxfHd\n\ 20 | fXpK9qRnmG6A4HRHC9B93pjTo6iBksRhIeSsTL94EbUJ625i0Lqg4i6NVQIDAQAB\n\ 21 | AoGBAIDGqJH/Pta9+GTzGovE0N0D9j1tUKPl/ocS/m4Ya7fgdQ36q8rTpyFICvan\n\ 22 | QUmL8sQsmZ2Nkygt0VSJy/VOr6niQmoi97PY0egxvvK5mtc/nxePCGwYLOMpB6ql\n\ 23 | 0UptotmvJU3tjyHZbksOf6LlzvpAgk7GnxLF1Cg/RJhH9ubBAkEA6b32mr52u3Uz\n\ 24 | BjbVWez1XBcxgwHk8A4NF9yCpHtVRY3751FZbrhy7oa+ZvYokxS4dzrepZlB1dqX\n\ 25 | IXaq7CgakQJBAMuwpG4N5x1/PfLODD7PYaJ5GSIx6BZoJObnx/42PrIm2gQdfs6W\n\ 26 | 1aClscqMyj5vSBF+cWWqu1i7j6+qugSswIUCQA3T3BPZcqKyUztp4QM53mX9RUOP\n\ 27 | yCBfZGzl8aCTXz8HIEDV8il3pezwcbEbnNjen+8Fv4giYd+p18j2ATSJRtECQGaE\n\ 28 | lG3Tz4PYG/zN2fnu9KwKmSzNw4srhY82D0GSWcHerhIuKjmeTw0Y+EAC1nPQHIy5\n\ 29 | gCd0Y/DIDgyTOCbML+UCQQClbgAoYnIpbTUklWH00Z1xr+Y95BOjb4lyjyIF98B2\n\ 30 | FA0nM8cHuN/VLKjjcrJUK47lZEOsjLv+qTl0i0Lp6giq\n\ 31 | -----END RSA PRIVATE KEY-----" 32 | 33 | #define DOMAIN "duncanthrax.net" 34 | #define SELECTOR "cheezburger" 35 | 36 | /* This small function signs the following message using the domain, 37 | * selector and RSA key above. It prints the signature header 38 | * followed by the message on STDOUT, so we can simply pipe that 39 | * to the verification test program (test_verify.c). 40 | * 41 | * Please note that this sample code skips on some error checking 42 | * and handling for the sake of clarity and brevity. 43 | */ 44 | 45 | char *test_message[] = { 46 | "From: Tom Kistner \r\n", 47 | "X-Folded-Header: line one\r\n\tline two\r\n", 48 | "To: PDKIM\r\nSubject: PDKIM Test\r\n\r\nTes", 49 | "t 3,4\r\nHeute bug ich, morgen fix ich.\r\n", 50 | NULL 51 | }; 52 | 53 | int main(int argc, char *argv[]) { 54 | FILE *debug; 55 | int i; 56 | 57 | pdkim_ctx *ctx; 58 | pdkim_signature *signature; 59 | 60 | /* pdkim_ctx *pdkim_init_sign(int mode, 61 | * char *domain, 62 | * char *selector, 63 | * char *rsa_privkey) 64 | * 65 | * Initialize context for signing. 66 | * 67 | * int mode 68 | * PDKIM_INPUT_NORMAL or PDKIM_INPUT_SMTP. When SMTP 69 | * input is used, the lib will deflate double-dots at 70 | * the start of atline to a single dot, and it will 71 | * stop processing input when a line with and single 72 | * dot is received (Excess input will simply be ignored). 73 | * 74 | * char *domain 75 | * The domain to sign as. This value will land in the 76 | * d= tag of the signature. 77 | * 78 | * char *selector 79 | * The selector string to use. This value will land in 80 | * the s= tag of the signature. 81 | * 82 | * char *rsa_privkey 83 | * The private RSA key, in ASCII armor. It MUST NOT be 84 | * encrypted. 85 | * 86 | * Returns: A pointer to a freshly allocated pdkim_ctx 87 | * context. 88 | */ 89 | ctx = pdkim_init_sign(PDKIM_INPUT_NORMAL, /* Input type */ 90 | DOMAIN, /* Domain */ 91 | SELECTOR, /* Selector */ 92 | RSA_PRIVKEY /* Private RSA key */ 93 | ); 94 | 95 | /* void pdkim_set_debug_stream(pdkim_ctx *ctx, 96 | * FILE *debug) 97 | * 98 | * Set up debugging stream. 99 | * 100 | * When PDKIM was compiled with DEBUG defined (which is the 101 | * recommended default), you can set up a stream where it 102 | * sends debug output to. In this example, we simply use 103 | * STDERR (fd 2) for that purpose. If you don't set a debug 104 | * stream, no debug output is generated. 105 | */ 106 | debug = fdopen(2,"a"); 107 | pdkim_set_debug_stream(ctx,debug); 108 | 109 | /* int pdkim_set_optional(pdkim_ctx *ctx, 110 | * char *sign_headers, 111 | * char *identity, 112 | * int canon_headers, 113 | * int canon_body, 114 | * long bodylength, 115 | * int algo, 116 | * unsigned long created, 117 | * unsigned long expires) 118 | * 119 | * OPTIONAL: Set additional optional signing options. If you do 120 | * not use this function, sensible defaults (see below) are used. 121 | * Any strings you pass in are dup'ed, so you can safely release 122 | * your copy even before calling pdkim_free() on your context. 123 | * 124 | * char *sign_headers (default NULL) 125 | * Colon-separated list of header names. Headers with 126 | * a name matching the list will be included in the 127 | * signature. When this is NULL, the list of headers 128 | * recommended in RFC4781 will be used. 129 | * 130 | * char *identity (default NULL) 131 | * An identity string as described in RFC4781. It will 132 | * be put into the i= tag of the signature. 133 | * 134 | * int canon_headers (default PDKIM_CANON_SIMPLE) 135 | * Canonicalization algorithm to use for headers. One 136 | * of PDKIM_CANON_SIMPLE or PDKIM_CANON_RELAXED. 137 | * 138 | * int canon_body (default PDKIM_CANON_SIMPLE) 139 | * Canonicalization algorithm to use for the body. One 140 | * of PDKIM_CANON_SIMPLE or PDKIM_CANON_RELAXED. 141 | * 142 | * long bodylength (default -1) 143 | * Amount of canonicalized body bytes to include in 144 | * the body hash calculation. A value of 0 means that 145 | * the body is not included in the signature. A value 146 | * of -1 (the default) means that there is no limit. 147 | * 148 | * int algo (default PDKIM_ALGO_RSA_SHA256) 149 | * One of PDKIM_ALGO_RSA_SHA256 or PDKIM_ALGO_RSA_SHA1. 150 | * 151 | * unsigned long created (default 0) 152 | * Seconds since the epoch, describing when the signature 153 | * was created. This is copied to the t= tag of the 154 | * signature. Setting a value of 0 (the default) omits 155 | * the tag from the signature. 156 | * 157 | * unsigned long expires (default 0) 158 | * Seconds since the epoch, describing when the signature 159 | * expires. This is copied to the x= tag of the 160 | * signature. Setting a value of 0 (the default) omits 161 | * the tag from the signature. 162 | * 163 | * Returns: 0 (PDKIM_OK) for success or a PDKIM_ERR_* constant 164 | */ 165 | pdkim_set_optional(ctx, NULL, NULL, 166 | PDKIM_CANON_SIMPLE, PDKIM_CANON_SIMPLE, 167 | -1, PDKIM_ALGO_RSA_SHA256, 0, 0); 168 | 169 | /* int pdkim_feed(pdkim_ctx *ctx, 170 | * char *data, 171 | * int data_len) 172 | * 173 | * (Repeatedly) feed data to the signing algorithm. The message 174 | * data MUST use CRLF line endings (like SMTP uses on the 175 | * wire). The data chunks do not need to be a "line" - you 176 | * can split chunks at arbitrary locations. 177 | * 178 | * char *data 179 | * Pointer to data to feed. Please note that despite 180 | * the example given below, this is not necessarily a 181 | * C string. 182 | * 183 | * int data_len 184 | * Length of data being fed, in bytes. 185 | * 186 | * Returns: 0 (PDKIM_OK) for success or a PDKIM_ERR_* constant 187 | */ 188 | i = 0; 189 | while (test_message[i] != NULL) { 190 | if (pdkim_feed(ctx, 191 | test_message[i], 192 | strlen(test_message[i])) != PDKIM_OK) { 193 | printf("pdkim_feed() error\n"); 194 | goto BAIL; 195 | } 196 | i++; 197 | } 198 | 199 | /* int pdkim_feed_finish(pdkim_ctx *ctx, 200 | * pdkim_signature **signature, 201 | * 202 | * Signal end-of-message and retrieve the signature block. 203 | * 204 | * pdkim_signature **signature 205 | * Pass in a pointer to a pdkim_signature pointer. 206 | * If the function returns PDKIM_OK, it will be set 207 | * up to point to a freshly allocated pdkim_signature 208 | * block. See pdkim.h for documentation on what that 209 | * block contains. Hint: Most implementations will 210 | * simply want to retrieve a ready-to-use 211 | * DKIM-Signature header, which can be found in 212 | * *signature->signature_header. See the code below. 213 | * 214 | * Returns: 0 (PDKIM_OK) for success or a PDKIM_ERR_* constant 215 | */ 216 | if (pdkim_feed_finish(ctx,&signature) == PDKIM_OK) { 217 | 218 | /* Print signature to STDOUT, followed by the original 219 | * message. We can then pipe the output directly to 220 | * test_verify.c. 221 | */ 222 | printf(signature->signature_header); 223 | printf("\r\n"); 224 | 225 | i = 0; 226 | while (test_message[i] != NULL) { 227 | printf(test_message[i]); 228 | i++; 229 | } 230 | 231 | } 232 | 233 | BAIL: 234 | /* void pdkim_free_ctx(pdkim_ctx *ctx) 235 | * 236 | * Free all allocated memory blocks referenced from 237 | * the context, as well as the context itself. 238 | */ 239 | pdkim_free_ctx(ctx); 240 | 241 | fclose(debug); 242 | } 243 | -------------------------------------------------------------------------------- /pdkim.h: -------------------------------------------------------------------------------- 1 | /* 2 | * PDKIM - a RFC4871 (DKIM) implementation 3 | * 4 | * Copyright (C) 2009 Tom Kistner 5 | * 6 | * http://duncanthrax.net/pdkim/ 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License along 19 | * with this program; if not, write to the Free Software Foundation, Inc., 20 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | 23 | 24 | /* -------------------------------------------------------------------------- */ 25 | /* Debugging. This can also be enabled/disabled at run-time. I recommend to 26 | leave it defined. */ 27 | #define PDKIM_DEBUG 28 | 29 | /* -------------------------------------------------------------------------- */ 30 | /* Length of the preallocated buffer for the "answer" from the dns/txt 31 | callback function. */ 32 | #define PDKIM_DNS_TXT_MAX_RECLEN 4096 33 | 34 | /* -------------------------------------------------------------------------- */ 35 | /* Function success / error codes */ 36 | #define PDKIM_OK 0 37 | #define PDKIM_FAIL -1 38 | #define PDKIM_ERR_OOM -100 39 | #define PDKIM_ERR_RSA_PRIVKEY -101 40 | #define PDKIM_ERR_RSA_SIGNING -102 41 | #define PDKIM_ERR_LONG_LINE -103 42 | #define PDKIM_ERR_BUFFER_TOO_SMALL -104 43 | 44 | /* -------------------------------------------------------------------------- */ 45 | /* Main/Extended verification status */ 46 | #define PDKIM_VERIFY_NONE 0 47 | #define PDKIM_VERIFY_INVALID 1 48 | #define PDKIM_VERIFY_FAIL 2 49 | #define PDKIM_VERIFY_PASS 3 50 | 51 | #define PDKIM_VERIFY_FAIL_BODY 1 52 | #define PDKIM_VERIFY_FAIL_MESSAGE 2 53 | #define PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE 3 54 | #define PDKIM_VERIFY_INVALID_BUFFER_SIZE 4 55 | #define PDKIM_VERIFY_INVALID_PUBKEY_PARSING 5 56 | 57 | /* -------------------------------------------------------------------------- */ 58 | /* Some parameter values */ 59 | #define PDKIM_QUERYMETHOD_DNS_TXT 0 60 | 61 | #define PDKIM_ALGO_RSA_SHA256 0 62 | #define PDKIM_ALGO_RSA_SHA1 1 63 | 64 | #define PDKIM_CANON_SIMPLE 0 65 | #define PDKIM_CANON_RELAXED 1 66 | 67 | #define PDKIM_HASH_SHA256 0 68 | #define PDKIM_HASH_SHA1 1 69 | 70 | #define PDKIM_KEYTYPE_RSA 0 71 | 72 | /* -------------------------------------------------------------------------- */ 73 | /* Some required forward declarations, please ignore */ 74 | typedef struct pdkim_stringlist pdkim_stringlist; 75 | typedef struct pdkim_str pdkim_str; 76 | typedef struct sha1_context sha1_context; 77 | typedef struct sha2_context sha2_context; 78 | #define HAVE_SHA1_CONTEXT 79 | #define HAVE_SHA2_CONTEXT 80 | 81 | /* -------------------------------------------------------------------------- */ 82 | /* Some concessions towards Redmond */ 83 | #ifdef WINDOWS 84 | #define snprintf _snprintf 85 | #define strcasecmp _stricmp 86 | #define strncasecmp _strnicmp 87 | #define DLLEXPORT __declspec(dllexport) 88 | #else 89 | #define DLLEXPORT 90 | #endif 91 | 92 | 93 | /* -------------------------------------------------------------------------- */ 94 | /* Public key as (usually) fetched from DNS */ 95 | typedef struct pdkim_pubkey { 96 | char *version; /* v= */ 97 | char *granularity; /* g= */ 98 | 99 | char *hashes; /* h= */ 100 | char *keytype; /* k= */ 101 | char *srvtype; /* s= */ 102 | char *notes; /* n= */ 103 | 104 | char *key; /* p= */ 105 | int key_len; 106 | 107 | int testing; /* t=y */ 108 | int no_subdomaining; /* t=s */ 109 | } pdkim_pubkey; 110 | 111 | /* -------------------------------------------------------------------------- */ 112 | /* Signature as it appears in a DKIM-Signature header */ 113 | typedef struct pdkim_signature { 114 | 115 | /* Bits stored in a DKIM signature header --------------------------- */ 116 | 117 | /* (v=) The version, as an integer. Currently, always "1" */ 118 | int version; 119 | 120 | /* (a=) The signature algorithm. Either PDKIM_ALGO_RSA_SHA256 121 | or PDKIM_ALGO_RSA_SHA1 */ 122 | int algo; 123 | 124 | /* (c=x/) Header canonicalization method. Either PDKIM_CANON_SIMPLE 125 | or PDKIM_CANON_RELAXED */ 126 | int canon_headers; 127 | 128 | /* (c=/x) Body canonicalization method. Either PDKIM_CANON_SIMPLE 129 | or PDKIM_CANON_RELAXED */ 130 | int canon_body; 131 | 132 | /* (q=) Query Method. Currently, only PDKIM_QUERYMETHOD_DNS_TXT 133 | is specified */ 134 | int querymethod; 135 | 136 | /* (s=) The selector string as given in the signature */ 137 | char *selector; 138 | 139 | /* (d=) The domain as given in the signature */ 140 | char *domain; 141 | 142 | /* (i=) The identity as given in the signature */ 143 | char *identity; 144 | 145 | /* (t=) Timestamp of signature creation */ 146 | unsigned long created; 147 | 148 | /* (x=) Timestamp of expiry of signature */ 149 | unsigned long expires; 150 | 151 | /* (l=) Amount of hashed body bytes (after canonicalization). Default 152 | is -1. Note: a value of 0 means that the body is unsigned! */ 153 | long bodylength; 154 | 155 | /* (h=) Colon-separated list of header names that are included in the 156 | signature */ 157 | char *headernames; 158 | 159 | /* (z=) */ 160 | char *copiedheaders; 161 | 162 | /* (b=) Raw signature data, along with its length in bytes */ 163 | char *sigdata; 164 | int sigdata_len; 165 | 166 | /* (bh=) Raw body hash data, along with its length in bytes */ 167 | char *bodyhash; 168 | int bodyhash_len; 169 | 170 | /* Folded DKIM-Signature: header. Singing only, NULL for verifying. 171 | Ready for insertion into the message. Note: Folded using CRLFTB, 172 | but final line terminator is NOT included. Note2: This buffer is 173 | free()d when you call pdkim_free_ctx(). */ 174 | char *signature_header; 175 | 176 | /* The main verification status. Verification only. One of: 177 | 178 | PDKIM_VERIFY_NONE Verification was not attempted. This status 179 | should not appear. 180 | 181 | PDKIM_VERIFY_INVALID There was an error while trying to verify 182 | the signature. A more precise description 183 | is available in verify_ext_status. 184 | 185 | PDKIM_VERIFY_FAIL Verification failed because either the body 186 | hash did not match, or the signature verification 187 | failed. This means the message was modified. 188 | Check verify_ext_status for the exact reason. 189 | 190 | PDKIM_VERIFY_PASS Verification succeeded. 191 | */ 192 | int verify_status; 193 | 194 | /* Extended verification status. Verification only. Depending on the value 195 | of verify_status, it can contain: 196 | 197 | For verify_status == PDKIM_VERIFY_INVALID: 198 | 199 | PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE 200 | Unable to retrieve a public key container. 201 | 202 | PDKIM_VERIFY_INVALID_BUFFER_SIZE 203 | Either the DNS name constructed to retrieve the public key record 204 | does not fit into PDKIM_DNS_TXT_MAX_NAMELEN bytes, or the retrieved 205 | record is longer than PDKIM_DNS_TXT_MAX_RECLEN bytes. 206 | 207 | PDKIM_VERIFY_INVALID_PUBKEY_PARSING 208 | (Syntax) error while parsing the retrieved public key record. 209 | 210 | 211 | For verify_status == PDKIM_VERIFY_FAIL: 212 | 213 | PDKIM_VERIFY_FAIL_BODY 214 | The calculated body hash does not match the advertised body hash 215 | from the bh= tag of the signature. 216 | 217 | PDKIM_VERIFY_FAIL_MESSAGE 218 | RSA verification of the signature (b= tag) failed. 219 | */ 220 | int verify_ext_status; 221 | 222 | /* Pointer to a public key record that was used to verify the signature. 223 | See pdkim_pubkey declaration above for more information. 224 | Caution: is NULL if signing or if no record was retrieved. */ 225 | pdkim_pubkey *pubkey; 226 | 227 | /* Pointer to the next pdkim_signature signature. NULL if signing or if 228 | this is the last signature. */ 229 | void *next; 230 | 231 | /* Properties below this point are used internally only ------------- */ 232 | 233 | /* Per-signature helper variables ----------------------------------- */ 234 | sha1_context *sha1_body; /* SHA1 block */ 235 | sha2_context *sha2_body; /* SHA256 block */ 236 | unsigned long signed_body_bytes; /* How many body bytes we hashed */ 237 | pdkim_stringlist *headers; /* Raw headers included in the sig */ 238 | /* Signing specific ------------------------------------------------- */ 239 | char *rsa_privkey; /* Private RSA key */ 240 | char *sign_headers; /* To-be-signed header names */ 241 | char *rawsig_no_b_val; /* Original signature header w/o b= tag value. */ 242 | } pdkim_signature; 243 | 244 | 245 | /* -------------------------------------------------------------------------- */ 246 | /* Context to keep state between all operations. */ 247 | #define PDKIM_MODE_SIGN 0 248 | #define PDKIM_MODE_VERIFY 1 249 | #define PDKIM_INPUT_NORMAL 0 250 | #define PDKIM_INPUT_SMTP 1 251 | typedef struct pdkim_ctx { 252 | 253 | /* PDKIM_MODE_VERIFY or PDKIM_MODE_SIGN */ 254 | int mode; 255 | 256 | /* PDKIM_INPUT_SMTP or PDKIM_INPUT_NORMAL */ 257 | int input_mode; 258 | 259 | /* One (signing) or several chained (verification) signatures */ 260 | pdkim_signature *sig; 261 | 262 | /* Callback for dns/txt query method (verification only) */ 263 | int(*dns_txt_callback)(char *, char *); 264 | 265 | /* Coder's little helpers */ 266 | pdkim_str *cur_header; 267 | char *linebuf; 268 | int linebuf_offset; 269 | int seen_lf; 270 | int seen_eod; 271 | int past_headers; 272 | int num_buffered_crlf; 273 | int num_headers; 274 | pdkim_stringlist *headers; /* Raw headers for verification */ 275 | 276 | #ifdef PDKIM_DEBUG 277 | /* A FILE pointer. When not NULL, debug output will be generated 278 | and sent to this stream */ 279 | FILE *debug_stream; 280 | #endif 281 | 282 | } pdkim_ctx; 283 | 284 | 285 | /* -------------------------------------------------------------------------- */ 286 | /* API functions. Please see the sample code in sample/test_sign.c and 287 | sample/test_verify.c for documentation. 288 | */ 289 | 290 | #ifdef __cplusplus 291 | extern "C" { 292 | #endif 293 | 294 | DLLEXPORT 295 | pdkim_ctx *pdkim_init_sign (int, char *, char *, char *); 296 | 297 | DLLEXPORT 298 | pdkim_ctx *pdkim_init_verify (int, int(*)(char *, char *)); 299 | 300 | DLLEXPORT 301 | int pdkim_set_optional (pdkim_ctx *, char *, char *,int, int, 302 | long, int, 303 | unsigned long, 304 | unsigned long); 305 | 306 | DLLEXPORT 307 | int pdkim_feed (pdkim_ctx *, char *, int); 308 | DLLEXPORT 309 | int pdkim_feed_finish (pdkim_ctx *, pdkim_signature **); 310 | 311 | DLLEXPORT 312 | void pdkim_free_ctx (pdkim_ctx *); 313 | 314 | #ifdef PDKIM_DEBUG 315 | DLLEXPORT 316 | void pdkim_set_debug_stream(pdkim_ctx *, FILE *); 317 | #endif 318 | 319 | #ifdef __cplusplus 320 | } 321 | #endif 322 | -------------------------------------------------------------------------------- /sha1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FIPS-180-1 compliant SHA-1 implementation 3 | * 4 | * Copyright (C) 2006-2010, Brainspark B.V. 5 | * 6 | * This file is part of PolarSSL (http://www.polarssl.org) 7 | * Lead Maintainer: Paul Bakker 8 | * 9 | * All rights reserved. 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; if not, write to the Free Software Foundation, Inc., 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 24 | */ 25 | /* 26 | * The SHA-1 standard was published by NIST in 1993. 27 | * 28 | * http://www.itl.nist.gov/fipspubs/fip180-1.htm 29 | */ 30 | 31 | #include "sha1.h" 32 | 33 | #include 34 | #include 35 | 36 | /* 37 | * 32-bit integer manipulation macros (big endian) 38 | */ 39 | #ifndef GET_ULONG_BE 40 | #define GET_ULONG_BE(n,b,i) \ 41 | { \ 42 | (n) = ( (unsigned long) (b)[(i) ] << 24 ) \ 43 | | ( (unsigned long) (b)[(i) + 1] << 16 ) \ 44 | | ( (unsigned long) (b)[(i) + 2] << 8 ) \ 45 | | ( (unsigned long) (b)[(i) + 3] ); \ 46 | } 47 | #endif 48 | 49 | #ifndef PUT_ULONG_BE 50 | #define PUT_ULONG_BE(n,b,i) \ 51 | { \ 52 | (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ 53 | (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ 54 | (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ 55 | (b)[(i) + 3] = (unsigned char) ( (n) ); \ 56 | } 57 | #endif 58 | 59 | /* 60 | * SHA-1 context setup 61 | */ 62 | void sha1_starts( sha1_context *ctx ) 63 | { 64 | ctx->total[0] = 0; 65 | ctx->total[1] = 0; 66 | 67 | ctx->state[0] = 0x67452301; 68 | ctx->state[1] = 0xEFCDAB89; 69 | ctx->state[2] = 0x98BADCFE; 70 | ctx->state[3] = 0x10325476; 71 | ctx->state[4] = 0xC3D2E1F0; 72 | } 73 | 74 | static void sha1_process( sha1_context *ctx, const unsigned char data[64] ) 75 | { 76 | unsigned long temp, W[16], A, B, C, D, E; 77 | 78 | GET_ULONG_BE( W[ 0], data, 0 ); 79 | GET_ULONG_BE( W[ 1], data, 4 ); 80 | GET_ULONG_BE( W[ 2], data, 8 ); 81 | GET_ULONG_BE( W[ 3], data, 12 ); 82 | GET_ULONG_BE( W[ 4], data, 16 ); 83 | GET_ULONG_BE( W[ 5], data, 20 ); 84 | GET_ULONG_BE( W[ 6], data, 24 ); 85 | GET_ULONG_BE( W[ 7], data, 28 ); 86 | GET_ULONG_BE( W[ 8], data, 32 ); 87 | GET_ULONG_BE( W[ 9], data, 36 ); 88 | GET_ULONG_BE( W[10], data, 40 ); 89 | GET_ULONG_BE( W[11], data, 44 ); 90 | GET_ULONG_BE( W[12], data, 48 ); 91 | GET_ULONG_BE( W[13], data, 52 ); 92 | GET_ULONG_BE( W[14], data, 56 ); 93 | GET_ULONG_BE( W[15], data, 60 ); 94 | 95 | #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) 96 | 97 | #define R(t) \ 98 | ( \ 99 | temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \ 100 | W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \ 101 | ( W[t & 0x0F] = S(temp,1) ) \ 102 | ) 103 | 104 | #define P(a,b,c,d,e,x) \ 105 | { \ 106 | e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ 107 | } 108 | 109 | A = ctx->state[0]; 110 | B = ctx->state[1]; 111 | C = ctx->state[2]; 112 | D = ctx->state[3]; 113 | E = ctx->state[4]; 114 | 115 | #define F(x,y,z) (z ^ (x & (y ^ z))) 116 | #define K 0x5A827999 117 | 118 | P( A, B, C, D, E, W[0] ); 119 | P( E, A, B, C, D, W[1] ); 120 | P( D, E, A, B, C, W[2] ); 121 | P( C, D, E, A, B, W[3] ); 122 | P( B, C, D, E, A, W[4] ); 123 | P( A, B, C, D, E, W[5] ); 124 | P( E, A, B, C, D, W[6] ); 125 | P( D, E, A, B, C, W[7] ); 126 | P( C, D, E, A, B, W[8] ); 127 | P( B, C, D, E, A, W[9] ); 128 | P( A, B, C, D, E, W[10] ); 129 | P( E, A, B, C, D, W[11] ); 130 | P( D, E, A, B, C, W[12] ); 131 | P( C, D, E, A, B, W[13] ); 132 | P( B, C, D, E, A, W[14] ); 133 | P( A, B, C, D, E, W[15] ); 134 | P( E, A, B, C, D, R(16) ); 135 | P( D, E, A, B, C, R(17) ); 136 | P( C, D, E, A, B, R(18) ); 137 | P( B, C, D, E, A, R(19) ); 138 | 139 | #undef K 140 | #undef F 141 | 142 | #define F(x,y,z) (x ^ y ^ z) 143 | #define K 0x6ED9EBA1 144 | 145 | P( A, B, C, D, E, R(20) ); 146 | P( E, A, B, C, D, R(21) ); 147 | P( D, E, A, B, C, R(22) ); 148 | P( C, D, E, A, B, R(23) ); 149 | P( B, C, D, E, A, R(24) ); 150 | P( A, B, C, D, E, R(25) ); 151 | P( E, A, B, C, D, R(26) ); 152 | P( D, E, A, B, C, R(27) ); 153 | P( C, D, E, A, B, R(28) ); 154 | P( B, C, D, E, A, R(29) ); 155 | P( A, B, C, D, E, R(30) ); 156 | P( E, A, B, C, D, R(31) ); 157 | P( D, E, A, B, C, R(32) ); 158 | P( C, D, E, A, B, R(33) ); 159 | P( B, C, D, E, A, R(34) ); 160 | P( A, B, C, D, E, R(35) ); 161 | P( E, A, B, C, D, R(36) ); 162 | P( D, E, A, B, C, R(37) ); 163 | P( C, D, E, A, B, R(38) ); 164 | P( B, C, D, E, A, R(39) ); 165 | 166 | #undef K 167 | #undef F 168 | 169 | #define F(x,y,z) ((x & y) | (z & (x | y))) 170 | #define K 0x8F1BBCDC 171 | 172 | P( A, B, C, D, E, R(40) ); 173 | P( E, A, B, C, D, R(41) ); 174 | P( D, E, A, B, C, R(42) ); 175 | P( C, D, E, A, B, R(43) ); 176 | P( B, C, D, E, A, R(44) ); 177 | P( A, B, C, D, E, R(45) ); 178 | P( E, A, B, C, D, R(46) ); 179 | P( D, E, A, B, C, R(47) ); 180 | P( C, D, E, A, B, R(48) ); 181 | P( B, C, D, E, A, R(49) ); 182 | P( A, B, C, D, E, R(50) ); 183 | P( E, A, B, C, D, R(51) ); 184 | P( D, E, A, B, C, R(52) ); 185 | P( C, D, E, A, B, R(53) ); 186 | P( B, C, D, E, A, R(54) ); 187 | P( A, B, C, D, E, R(55) ); 188 | P( E, A, B, C, D, R(56) ); 189 | P( D, E, A, B, C, R(57) ); 190 | P( C, D, E, A, B, R(58) ); 191 | P( B, C, D, E, A, R(59) ); 192 | 193 | #undef K 194 | #undef F 195 | 196 | #define F(x,y,z) (x ^ y ^ z) 197 | #define K 0xCA62C1D6 198 | 199 | P( A, B, C, D, E, R(60) ); 200 | P( E, A, B, C, D, R(61) ); 201 | P( D, E, A, B, C, R(62) ); 202 | P( C, D, E, A, B, R(63) ); 203 | P( B, C, D, E, A, R(64) ); 204 | P( A, B, C, D, E, R(65) ); 205 | P( E, A, B, C, D, R(66) ); 206 | P( D, E, A, B, C, R(67) ); 207 | P( C, D, E, A, B, R(68) ); 208 | P( B, C, D, E, A, R(69) ); 209 | P( A, B, C, D, E, R(70) ); 210 | P( E, A, B, C, D, R(71) ); 211 | P( D, E, A, B, C, R(72) ); 212 | P( C, D, E, A, B, R(73) ); 213 | P( B, C, D, E, A, R(74) ); 214 | P( A, B, C, D, E, R(75) ); 215 | P( E, A, B, C, D, R(76) ); 216 | P( D, E, A, B, C, R(77) ); 217 | P( C, D, E, A, B, R(78) ); 218 | P( B, C, D, E, A, R(79) ); 219 | 220 | #undef K 221 | #undef F 222 | 223 | ctx->state[0] += A; 224 | ctx->state[1] += B; 225 | ctx->state[2] += C; 226 | ctx->state[3] += D; 227 | ctx->state[4] += E; 228 | } 229 | 230 | /* 231 | * SHA-1 process buffer 232 | */ 233 | void sha1_update( sha1_context *ctx, const unsigned char *input, int ilen ) 234 | { 235 | int fill; 236 | unsigned long left; 237 | 238 | if( ilen <= 0 ) 239 | return; 240 | 241 | left = ctx->total[0] & 0x3F; 242 | fill = 64 - left; 243 | 244 | ctx->total[0] += ilen; 245 | ctx->total[0] &= 0xFFFFFFFF; 246 | 247 | if( ctx->total[0] < (unsigned long) ilen ) 248 | ctx->total[1]++; 249 | 250 | if( left && ilen >= fill ) 251 | { 252 | memcpy( (void *) (ctx->buffer + left), 253 | (void *) input, fill ); 254 | sha1_process( ctx, ctx->buffer ); 255 | input += fill; 256 | ilen -= fill; 257 | left = 0; 258 | } 259 | 260 | while( ilen >= 64 ) 261 | { 262 | sha1_process( ctx, input ); 263 | input += 64; 264 | ilen -= 64; 265 | } 266 | 267 | if( ilen > 0 ) 268 | { 269 | memcpy( (void *) (ctx->buffer + left), 270 | (void *) input, ilen ); 271 | } 272 | } 273 | 274 | static const unsigned char sha1_padding[64] = 275 | { 276 | 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 277 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 278 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 279 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 280 | }; 281 | 282 | /* 283 | * SHA-1 final digest 284 | */ 285 | void sha1_finish( sha1_context *ctx, unsigned char output[20] ) 286 | { 287 | unsigned long last, padn; 288 | unsigned long high, low; 289 | unsigned char msglen[8]; 290 | 291 | high = ( ctx->total[0] >> 29 ) 292 | | ( ctx->total[1] << 3 ); 293 | low = ( ctx->total[0] << 3 ); 294 | 295 | PUT_ULONG_BE( high, msglen, 0 ); 296 | PUT_ULONG_BE( low, msglen, 4 ); 297 | 298 | last = ctx->total[0] & 0x3F; 299 | padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); 300 | 301 | sha1_update( ctx, (unsigned char *) sha1_padding, padn ); 302 | sha1_update( ctx, msglen, 8 ); 303 | 304 | PUT_ULONG_BE( ctx->state[0], output, 0 ); 305 | PUT_ULONG_BE( ctx->state[1], output, 4 ); 306 | PUT_ULONG_BE( ctx->state[2], output, 8 ); 307 | PUT_ULONG_BE( ctx->state[3], output, 12 ); 308 | PUT_ULONG_BE( ctx->state[4], output, 16 ); 309 | } 310 | 311 | /* 312 | * output = SHA-1( input buffer ) 313 | */ 314 | void sha1( const unsigned char *input, int ilen, unsigned char output[20] ) 315 | { 316 | sha1_context ctx; 317 | 318 | sha1_starts( &ctx ); 319 | sha1_update( &ctx, input, ilen ); 320 | sha1_finish( &ctx, output ); 321 | 322 | memset( &ctx, 0, sizeof( sha1_context ) ); 323 | } 324 | 325 | /* 326 | * output = SHA-1( file contents ) 327 | */ 328 | int sha1_file( const char *path, unsigned char output[20] ) 329 | { 330 | FILE *f; 331 | size_t n; 332 | sha1_context ctx; 333 | unsigned char buf[1024]; 334 | 335 | if( ( f = fopen( path, "rb" ) ) == NULL ) 336 | return( 1 ); 337 | 338 | sha1_starts( &ctx ); 339 | 340 | while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) 341 | sha1_update( &ctx, buf, (int) n ); 342 | 343 | sha1_finish( &ctx, output ); 344 | 345 | memset( &ctx, 0, sizeof( sha1_context ) ); 346 | 347 | if( ferror( f ) != 0 ) 348 | { 349 | fclose( f ); 350 | return( 2 ); 351 | } 352 | 353 | fclose( f ); 354 | return( 0 ); 355 | } 356 | 357 | /* 358 | * SHA-1 HMAC context setup 359 | */ 360 | void sha1_hmac_starts( sha1_context *ctx, const unsigned char *key, int keylen ) 361 | { 362 | int i; 363 | unsigned char sum[20]; 364 | 365 | if( keylen > 64 ) 366 | { 367 | sha1( key, keylen, sum ); 368 | keylen = 20; 369 | key = sum; 370 | } 371 | 372 | memset( ctx->ipad, 0x36, 64 ); 373 | memset( ctx->opad, 0x5C, 64 ); 374 | 375 | for( i = 0; i < keylen; i++ ) 376 | { 377 | ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] ); 378 | ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] ); 379 | } 380 | 381 | sha1_starts( ctx ); 382 | sha1_update( ctx, ctx->ipad, 64 ); 383 | 384 | memset( sum, 0, sizeof( sum ) ); 385 | } 386 | 387 | /* 388 | * SHA-1 HMAC process buffer 389 | */ 390 | void sha1_hmac_update( sha1_context *ctx, const unsigned char *input, int ilen ) 391 | { 392 | sha1_update( ctx, input, ilen ); 393 | } 394 | 395 | /* 396 | * SHA-1 HMAC final digest 397 | */ 398 | void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] ) 399 | { 400 | unsigned char tmpbuf[20]; 401 | 402 | sha1_finish( ctx, tmpbuf ); 403 | sha1_starts( ctx ); 404 | sha1_update( ctx, ctx->opad, 64 ); 405 | sha1_update( ctx, tmpbuf, 20 ); 406 | sha1_finish( ctx, output ); 407 | 408 | memset( tmpbuf, 0, sizeof( tmpbuf ) ); 409 | } 410 | 411 | /* 412 | * SHA1 HMAC context reset 413 | */ 414 | void sha1_hmac_reset( sha1_context *ctx ) 415 | { 416 | sha1_starts( ctx ); 417 | sha1_update( ctx, ctx->ipad, 64 ); 418 | } 419 | 420 | /* 421 | * output = HMAC-SHA-1( hmac key, input buffer ) 422 | */ 423 | void sha1_hmac( const unsigned char *key, int keylen, 424 | const unsigned char *input, int ilen, 425 | unsigned char output[20] ) 426 | { 427 | sha1_context ctx; 428 | 429 | sha1_hmac_starts( &ctx, key, keylen ); 430 | sha1_hmac_update( &ctx, input, ilen ); 431 | sha1_hmac_finish( &ctx, output ); 432 | 433 | memset( &ctx, 0, sizeof( sha1_context ) ); 434 | } 435 | 436 | -------------------------------------------------------------------------------- /sha2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FIPS-180-2 compliant SHA-256 implementation 3 | * 4 | * Copyright (C) 2006-2010, Brainspark B.V. 5 | * 6 | * This file is part of PolarSSL (http://www.polarssl.org) 7 | * Lead Maintainer: Paul Bakker 8 | * 9 | * All rights reserved. 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; if not, write to the Free Software Foundation, Inc., 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 24 | */ 25 | /* 26 | * The SHA-256 Secure Hash Standard was published by NIST in 2002. 27 | * 28 | * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf 29 | */ 30 | 31 | #include "sha2.h" 32 | 33 | #include 34 | #include 35 | 36 | /* 37 | * 32-bit integer manipulation macros (big endian) 38 | */ 39 | #ifndef GET_ULONG_BE 40 | #define GET_ULONG_BE(n,b,i) \ 41 | { \ 42 | (n) = ( (unsigned long) (b)[(i) ] << 24 ) \ 43 | | ( (unsigned long) (b)[(i) + 1] << 16 ) \ 44 | | ( (unsigned long) (b)[(i) + 2] << 8 ) \ 45 | | ( (unsigned long) (b)[(i) + 3] ); \ 46 | } 47 | #endif 48 | 49 | #ifndef PUT_ULONG_BE 50 | #define PUT_ULONG_BE(n,b,i) \ 51 | { \ 52 | (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ 53 | (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ 54 | (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ 55 | (b)[(i) + 3] = (unsigned char) ( (n) ); \ 56 | } 57 | #endif 58 | 59 | /* 60 | * SHA-256 context setup 61 | */ 62 | void sha2_starts( sha2_context *ctx, int is224 ) 63 | { 64 | ctx->total[0] = 0; 65 | ctx->total[1] = 0; 66 | 67 | if( is224 == 0 ) 68 | { 69 | /* SHA-256 */ 70 | ctx->state[0] = 0x6A09E667; 71 | ctx->state[1] = 0xBB67AE85; 72 | ctx->state[2] = 0x3C6EF372; 73 | ctx->state[3] = 0xA54FF53A; 74 | ctx->state[4] = 0x510E527F; 75 | ctx->state[5] = 0x9B05688C; 76 | ctx->state[6] = 0x1F83D9AB; 77 | ctx->state[7] = 0x5BE0CD19; 78 | } 79 | else 80 | { 81 | /* SHA-224 */ 82 | ctx->state[0] = 0xC1059ED8; 83 | ctx->state[1] = 0x367CD507; 84 | ctx->state[2] = 0x3070DD17; 85 | ctx->state[3] = 0xF70E5939; 86 | ctx->state[4] = 0xFFC00B31; 87 | ctx->state[5] = 0x68581511; 88 | ctx->state[6] = 0x64F98FA7; 89 | ctx->state[7] = 0xBEFA4FA4; 90 | } 91 | 92 | ctx->is224 = is224; 93 | } 94 | 95 | static void sha2_process( sha2_context *ctx, const unsigned char data[64] ) 96 | { 97 | unsigned long temp1, temp2, W[64]; 98 | unsigned long A, B, C, D, E, F, G, H; 99 | 100 | GET_ULONG_BE( W[ 0], data, 0 ); 101 | GET_ULONG_BE( W[ 1], data, 4 ); 102 | GET_ULONG_BE( W[ 2], data, 8 ); 103 | GET_ULONG_BE( W[ 3], data, 12 ); 104 | GET_ULONG_BE( W[ 4], data, 16 ); 105 | GET_ULONG_BE( W[ 5], data, 20 ); 106 | GET_ULONG_BE( W[ 6], data, 24 ); 107 | GET_ULONG_BE( W[ 7], data, 28 ); 108 | GET_ULONG_BE( W[ 8], data, 32 ); 109 | GET_ULONG_BE( W[ 9], data, 36 ); 110 | GET_ULONG_BE( W[10], data, 40 ); 111 | GET_ULONG_BE( W[11], data, 44 ); 112 | GET_ULONG_BE( W[12], data, 48 ); 113 | GET_ULONG_BE( W[13], data, 52 ); 114 | GET_ULONG_BE( W[14], data, 56 ); 115 | GET_ULONG_BE( W[15], data, 60 ); 116 | 117 | #define SHR(x,n) ((x & 0xFFFFFFFF) >> n) 118 | #define ROTR(x,n) (SHR(x,n) | (x << (32 - n))) 119 | 120 | #define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3)) 121 | #define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10)) 122 | 123 | #define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22)) 124 | #define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25)) 125 | 126 | #define F0(x,y,z) ((x & y) | (z & (x | y))) 127 | #define F1(x,y,z) (z ^ (x & (y ^ z))) 128 | 129 | #define R(t) \ 130 | ( \ 131 | W[t] = S1(W[t - 2]) + W[t - 7] + \ 132 | S0(W[t - 15]) + W[t - 16] \ 133 | ) 134 | 135 | #define P(a,b,c,d,e,f,g,h,x,K) \ 136 | { \ 137 | temp1 = h + S3(e) + F1(e,f,g) + K + x; \ 138 | temp2 = S2(a) + F0(a,b,c); \ 139 | d += temp1; h = temp1 + temp2; \ 140 | } 141 | 142 | A = ctx->state[0]; 143 | B = ctx->state[1]; 144 | C = ctx->state[2]; 145 | D = ctx->state[3]; 146 | E = ctx->state[4]; 147 | F = ctx->state[5]; 148 | G = ctx->state[6]; 149 | H = ctx->state[7]; 150 | 151 | P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98 ); 152 | P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491 ); 153 | P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF ); 154 | P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5 ); 155 | P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B ); 156 | P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1 ); 157 | P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4 ); 158 | P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5 ); 159 | P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98 ); 160 | P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01 ); 161 | P( G, H, A, B, C, D, E, F, W[10], 0x243185BE ); 162 | P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3 ); 163 | P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74 ); 164 | P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE ); 165 | P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7 ); 166 | P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174 ); 167 | P( A, B, C, D, E, F, G, H, R(16), 0xE49B69C1 ); 168 | P( H, A, B, C, D, E, F, G, R(17), 0xEFBE4786 ); 169 | P( G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6 ); 170 | P( F, G, H, A, B, C, D, E, R(19), 0x240CA1CC ); 171 | P( E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F ); 172 | P( D, E, F, G, H, A, B, C, R(21), 0x4A7484AA ); 173 | P( C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC ); 174 | P( B, C, D, E, F, G, H, A, R(23), 0x76F988DA ); 175 | P( A, B, C, D, E, F, G, H, R(24), 0x983E5152 ); 176 | P( H, A, B, C, D, E, F, G, R(25), 0xA831C66D ); 177 | P( G, H, A, B, C, D, E, F, R(26), 0xB00327C8 ); 178 | P( F, G, H, A, B, C, D, E, R(27), 0xBF597FC7 ); 179 | P( E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3 ); 180 | P( D, E, F, G, H, A, B, C, R(29), 0xD5A79147 ); 181 | P( C, D, E, F, G, H, A, B, R(30), 0x06CA6351 ); 182 | P( B, C, D, E, F, G, H, A, R(31), 0x14292967 ); 183 | P( A, B, C, D, E, F, G, H, R(32), 0x27B70A85 ); 184 | P( H, A, B, C, D, E, F, G, R(33), 0x2E1B2138 ); 185 | P( G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC ); 186 | P( F, G, H, A, B, C, D, E, R(35), 0x53380D13 ); 187 | P( E, F, G, H, A, B, C, D, R(36), 0x650A7354 ); 188 | P( D, E, F, G, H, A, B, C, R(37), 0x766A0ABB ); 189 | P( C, D, E, F, G, H, A, B, R(38), 0x81C2C92E ); 190 | P( B, C, D, E, F, G, H, A, R(39), 0x92722C85 ); 191 | P( A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1 ); 192 | P( H, A, B, C, D, E, F, G, R(41), 0xA81A664B ); 193 | P( G, H, A, B, C, D, E, F, R(42), 0xC24B8B70 ); 194 | P( F, G, H, A, B, C, D, E, R(43), 0xC76C51A3 ); 195 | P( E, F, G, H, A, B, C, D, R(44), 0xD192E819 ); 196 | P( D, E, F, G, H, A, B, C, R(45), 0xD6990624 ); 197 | P( C, D, E, F, G, H, A, B, R(46), 0xF40E3585 ); 198 | P( B, C, D, E, F, G, H, A, R(47), 0x106AA070 ); 199 | P( A, B, C, D, E, F, G, H, R(48), 0x19A4C116 ); 200 | P( H, A, B, C, D, E, F, G, R(49), 0x1E376C08 ); 201 | P( G, H, A, B, C, D, E, F, R(50), 0x2748774C ); 202 | P( F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5 ); 203 | P( E, F, G, H, A, B, C, D, R(52), 0x391C0CB3 ); 204 | P( D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A ); 205 | P( C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F ); 206 | P( B, C, D, E, F, G, H, A, R(55), 0x682E6FF3 ); 207 | P( A, B, C, D, E, F, G, H, R(56), 0x748F82EE ); 208 | P( H, A, B, C, D, E, F, G, R(57), 0x78A5636F ); 209 | P( G, H, A, B, C, D, E, F, R(58), 0x84C87814 ); 210 | P( F, G, H, A, B, C, D, E, R(59), 0x8CC70208 ); 211 | P( E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA ); 212 | P( D, E, F, G, H, A, B, C, R(61), 0xA4506CEB ); 213 | P( C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7 ); 214 | P( B, C, D, E, F, G, H, A, R(63), 0xC67178F2 ); 215 | 216 | ctx->state[0] += A; 217 | ctx->state[1] += B; 218 | ctx->state[2] += C; 219 | ctx->state[3] += D; 220 | ctx->state[4] += E; 221 | ctx->state[5] += F; 222 | ctx->state[6] += G; 223 | ctx->state[7] += H; 224 | } 225 | 226 | /* 227 | * SHA-256 process buffer 228 | */ 229 | void sha2_update( sha2_context *ctx, const unsigned char *input, int ilen ) 230 | { 231 | int fill; 232 | unsigned long left; 233 | 234 | if( ilen <= 0 ) 235 | return; 236 | 237 | left = ctx->total[0] & 0x3F; 238 | fill = 64 - left; 239 | 240 | ctx->total[0] += ilen; 241 | ctx->total[0] &= 0xFFFFFFFF; 242 | 243 | if( ctx->total[0] < (unsigned long) ilen ) 244 | ctx->total[1]++; 245 | 246 | if( left && ilen >= fill ) 247 | { 248 | memcpy( (void *) (ctx->buffer + left), 249 | (void *) input, fill ); 250 | sha2_process( ctx, ctx->buffer ); 251 | input += fill; 252 | ilen -= fill; 253 | left = 0; 254 | } 255 | 256 | while( ilen >= 64 ) 257 | { 258 | sha2_process( ctx, input ); 259 | input += 64; 260 | ilen -= 64; 261 | } 262 | 263 | if( ilen > 0 ) 264 | { 265 | memcpy( (void *) (ctx->buffer + left), 266 | (void *) input, ilen ); 267 | } 268 | } 269 | 270 | static const unsigned char sha2_padding[64] = 271 | { 272 | 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 273 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 274 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 275 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 276 | }; 277 | 278 | /* 279 | * SHA-256 final digest 280 | */ 281 | void sha2_finish( sha2_context *ctx, unsigned char output[32] ) 282 | { 283 | unsigned long last, padn; 284 | unsigned long high, low; 285 | unsigned char msglen[8]; 286 | 287 | high = ( ctx->total[0] >> 29 ) 288 | | ( ctx->total[1] << 3 ); 289 | low = ( ctx->total[0] << 3 ); 290 | 291 | PUT_ULONG_BE( high, msglen, 0 ); 292 | PUT_ULONG_BE( low, msglen, 4 ); 293 | 294 | last = ctx->total[0] & 0x3F; 295 | padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); 296 | 297 | sha2_update( ctx, (unsigned char *) sha2_padding, padn ); 298 | sha2_update( ctx, msglen, 8 ); 299 | 300 | PUT_ULONG_BE( ctx->state[0], output, 0 ); 301 | PUT_ULONG_BE( ctx->state[1], output, 4 ); 302 | PUT_ULONG_BE( ctx->state[2], output, 8 ); 303 | PUT_ULONG_BE( ctx->state[3], output, 12 ); 304 | PUT_ULONG_BE( ctx->state[4], output, 16 ); 305 | PUT_ULONG_BE( ctx->state[5], output, 20 ); 306 | PUT_ULONG_BE( ctx->state[6], output, 24 ); 307 | 308 | if( ctx->is224 == 0 ) 309 | PUT_ULONG_BE( ctx->state[7], output, 28 ); 310 | } 311 | 312 | /* 313 | * output = SHA-256( input buffer ) 314 | */ 315 | void sha2( const unsigned char *input, int ilen, 316 | unsigned char output[32], int is224 ) 317 | { 318 | sha2_context ctx; 319 | 320 | sha2_starts( &ctx, is224 ); 321 | sha2_update( &ctx, input, ilen ); 322 | sha2_finish( &ctx, output ); 323 | 324 | memset( &ctx, 0, sizeof( sha2_context ) ); 325 | } 326 | 327 | /* 328 | * output = SHA-256( file contents ) 329 | */ 330 | int sha2_file( const char *path, unsigned char output[32], int is224 ) 331 | { 332 | FILE *f; 333 | size_t n; 334 | sha2_context ctx; 335 | unsigned char buf[1024]; 336 | 337 | if( ( f = fopen( path, "rb" ) ) == NULL ) 338 | return( 1 ); 339 | 340 | sha2_starts( &ctx, is224 ); 341 | 342 | while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) 343 | sha2_update( &ctx, buf, (int) n ); 344 | 345 | sha2_finish( &ctx, output ); 346 | 347 | memset( &ctx, 0, sizeof( sha2_context ) ); 348 | 349 | if( ferror( f ) != 0 ) 350 | { 351 | fclose( f ); 352 | return( 2 ); 353 | } 354 | 355 | fclose( f ); 356 | return( 0 ); 357 | } 358 | 359 | /* 360 | * SHA-256 HMAC context setup 361 | */ 362 | void sha2_hmac_starts( sha2_context *ctx, const unsigned char *key, int keylen, 363 | int is224 ) 364 | { 365 | int i; 366 | unsigned char sum[32]; 367 | 368 | if( keylen > 64 ) 369 | { 370 | sha2( key, keylen, sum, is224 ); 371 | keylen = ( is224 ) ? 28 : 32; 372 | key = sum; 373 | } 374 | 375 | memset( ctx->ipad, 0x36, 64 ); 376 | memset( ctx->opad, 0x5C, 64 ); 377 | 378 | for( i = 0; i < keylen; i++ ) 379 | { 380 | ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] ); 381 | ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] ); 382 | } 383 | 384 | sha2_starts( ctx, is224 ); 385 | sha2_update( ctx, ctx->ipad, 64 ); 386 | 387 | memset( sum, 0, sizeof( sum ) ); 388 | } 389 | 390 | /* 391 | * SHA-256 HMAC process buffer 392 | */ 393 | void sha2_hmac_update( sha2_context *ctx, const unsigned char *input, int ilen ) 394 | { 395 | sha2_update( ctx, input, ilen ); 396 | } 397 | 398 | /* 399 | * SHA-256 HMAC final digest 400 | */ 401 | void sha2_hmac_finish( sha2_context *ctx, unsigned char output[32] ) 402 | { 403 | int is224, hlen; 404 | unsigned char tmpbuf[32]; 405 | 406 | is224 = ctx->is224; 407 | hlen = ( is224 == 0 ) ? 32 : 28; 408 | 409 | sha2_finish( ctx, tmpbuf ); 410 | sha2_starts( ctx, is224 ); 411 | sha2_update( ctx, ctx->opad, 64 ); 412 | sha2_update( ctx, tmpbuf, hlen ); 413 | sha2_finish( ctx, output ); 414 | 415 | memset( tmpbuf, 0, sizeof( tmpbuf ) ); 416 | } 417 | 418 | /* 419 | * SHA-256 HMAC context reset 420 | */ 421 | void sha2_hmac_reset( sha2_context *ctx ) 422 | { 423 | sha2_starts( ctx, ctx->is224 ); 424 | sha2_update( ctx, ctx->ipad, 64 ); 425 | } 426 | 427 | /* 428 | * output = HMAC-SHA-256( hmac key, input buffer ) 429 | */ 430 | void sha2_hmac( const unsigned char *key, int keylen, 431 | const unsigned char *input, int ilen, 432 | unsigned char output[32], int is224 ) 433 | { 434 | sha2_context ctx; 435 | 436 | sha2_hmac_starts( &ctx, key, keylen, is224 ); 437 | sha2_hmac_update( &ctx, input, ilen ); 438 | sha2_hmac_finish( &ctx, output ); 439 | 440 | memset( &ctx, 0, sizeof( sha2_context ) ); 441 | } 442 | 443 | -------------------------------------------------------------------------------- /rsa.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file rsa.h 3 | * 4 | * Copyright (C) 2006-2010, Brainspark B.V. 5 | * 6 | * This file is part of PolarSSL (http://www.polarssl.org) 7 | * Lead Maintainer: Paul Bakker 8 | * 9 | * All rights reserved. 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; if not, write to the Free Software Foundation, Inc., 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 24 | */ 25 | #ifndef POLARSSL_RSA_H 26 | #define POLARSSL_RSA_H 27 | 28 | #include "bignum.h" 29 | 30 | /* 31 | * RSA Error codes 32 | */ 33 | #define POLARSSL_ERR_RSA_BAD_INPUT_DATA -0x0400 34 | #define POLARSSL_ERR_RSA_INVALID_PADDING -0x0410 35 | #define POLARSSL_ERR_RSA_KEY_GEN_FAILED -0x0420 36 | #define POLARSSL_ERR_RSA_KEY_CHECK_FAILED -0x0430 37 | #define POLARSSL_ERR_RSA_PUBLIC_FAILED -0x0440 38 | #define POLARSSL_ERR_RSA_PRIVATE_FAILED -0x0450 39 | #define POLARSSL_ERR_RSA_VERIFY_FAILED -0x0460 40 | #define POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE -0x0470 41 | #define POLARSSL_ERR_RSA_RNG_FAILED -0x0480 42 | 43 | /* *************** begin copy from x509.h ************************/ 44 | /* 45 | * ASN1 Error codes 46 | * 47 | * These error codes will be OR'ed to X509 error codes for 48 | * higher error granularity. 49 | */ 50 | #define POLARSSL_ERR_ASN1_OUT_OF_DATA 0x0014 51 | #define POLARSSL_ERR_ASN1_UNEXPECTED_TAG 0x0016 52 | #define POLARSSL_ERR_ASN1_INVALID_LENGTH 0x0018 53 | #define POLARSSL_ERR_ASN1_LENGTH_MISMATCH 0x001A 54 | #define POLARSSL_ERR_ASN1_INVALID_DATA 0x001C 55 | 56 | /* 57 | * X509 Error codes 58 | */ 59 | #define POLARSSL_ERR_X509_FEATURE_UNAVAILABLE -0x0020 60 | #define POLARSSL_ERR_X509_CERT_INVALID_PEM -0x0040 61 | #define POLARSSL_ERR_X509_CERT_INVALID_FORMAT -0x0060 62 | #define POLARSSL_ERR_X509_CERT_INVALID_VERSION -0x0080 63 | #define POLARSSL_ERR_X509_CERT_INVALID_SERIAL -0x00A0 64 | #define POLARSSL_ERR_X509_CERT_INVALID_ALG -0x00C0 65 | #define POLARSSL_ERR_X509_CERT_INVALID_NAME -0x00E0 66 | #define POLARSSL_ERR_X509_CERT_INVALID_DATE -0x0100 67 | #define POLARSSL_ERR_X509_CERT_INVALID_PUBKEY -0x0120 68 | #define POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE -0x0140 69 | #define POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS -0x0160 70 | #define POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION -0x0180 71 | #define POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG -0x01A0 72 | #define POLARSSL_ERR_X509_CERT_UNKNOWN_PK_ALG -0x01C0 73 | #define POLARSSL_ERR_X509_CERT_SIG_MISMATCH -0x01E0 74 | #define POLARSSL_ERR_X509_CERT_VERIFY_FAILED -0x0200 75 | #define POLARSSL_ERR_X509_KEY_INVALID_PEM -0x0220 76 | #define POLARSSL_ERR_X509_KEY_INVALID_VERSION -0x0240 77 | #define POLARSSL_ERR_X509_KEY_INVALID_FORMAT -0x0260 78 | #define POLARSSL_ERR_X509_KEY_INVALID_ENC_IV -0x0280 79 | #define POLARSSL_ERR_X509_KEY_UNKNOWN_ENC_ALG -0x02A0 80 | #define POLARSSL_ERR_X509_KEY_PASSWORD_REQUIRED -0x02C0 81 | #define POLARSSL_ERR_X509_KEY_PASSWORD_MISMATCH -0x02E0 82 | #define POLARSSL_ERR_X509_POINT_ERROR -0x0300 83 | #define POLARSSL_ERR_X509_VALUE_TO_LENGTH -0x0320 84 | 85 | /* 86 | * DER constants 87 | */ 88 | #define ASN1_BOOLEAN 0x01 89 | #define ASN1_INTEGER 0x02 90 | #define ASN1_BIT_STRING 0x03 91 | #define ASN1_OCTET_STRING 0x04 92 | #define ASN1_NULL 0x05 93 | #define ASN1_OID 0x06 94 | #define ASN1_UTF8_STRING 0x0C 95 | #define ASN1_SEQUENCE 0x10 96 | #define ASN1_SET 0x11 97 | #define ASN1_PRINTABLE_STRING 0x13 98 | #define ASN1_T61_STRING 0x14 99 | #define ASN1_IA5_STRING 0x16 100 | #define ASN1_UTC_TIME 0x17 101 | #define ASN1_GENERALIZED_TIME 0x18 102 | #define ASN1_UNIVERSAL_STRING 0x1C 103 | #define ASN1_BMP_STRING 0x1E 104 | #define ASN1_PRIMITIVE 0x00 105 | #define ASN1_CONSTRUCTED 0x20 106 | #define ASN1_CONTEXT_SPECIFIC 0x80 107 | /* *************** end copy from x509.h ************************/ 108 | 109 | /* 110 | * PKCS#1 constants 111 | */ 112 | #define SIG_RSA_RAW 0 113 | #define SIG_RSA_MD2 2 114 | #define SIG_RSA_MD4 3 115 | #define SIG_RSA_MD5 4 116 | #define SIG_RSA_SHA1 5 117 | #define SIG_RSA_SHA224 14 118 | #define SIG_RSA_SHA256 11 119 | #define SIG_RSA_SHA384 12 120 | #define SIG_RSA_SHA512 13 121 | 122 | #define RSA_PUBLIC 0 123 | #define RSA_PRIVATE 1 124 | 125 | #define RSA_PKCS_V15 0 126 | #define RSA_PKCS_V21 1 127 | 128 | #define RSA_SIGN 1 129 | #define RSA_CRYPT 2 130 | 131 | #define ASN1_STR_CONSTRUCTED_SEQUENCE "\x30" 132 | #define ASN1_STR_NULL "\x05" 133 | #define ASN1_STR_OID "\x06" 134 | #define ASN1_STR_OCTET_STRING "\x04" 135 | 136 | #define OID_DIGEST_ALG_MDX "\x2A\x86\x48\x86\xF7\x0D\x02\x00" 137 | #define OID_HASH_ALG_SHA1 "\x2b\x0e\x03\x02\x1a" 138 | #define OID_HASH_ALG_SHA2X "\x60\x86\x48\x01\x65\x03\x04\x02\x00" 139 | 140 | #define OID_ISO_MEMBER_BODIES "\x2a" 141 | #define OID_ISO_IDENTIFIED_ORG "\x2b" 142 | 143 | /* 144 | * ISO Member bodies OID parts 145 | */ 146 | #define OID_COUNTRY_US "\x86\x48" 147 | #define OID_RSA_DATA_SECURITY "\x86\xf7\x0d" 148 | 149 | /* 150 | * ISO Identified organization OID parts 151 | */ 152 | #define OID_OIW_SECSIG_SHA1 "\x0e\x03\x02\x1a" 153 | 154 | /* 155 | * DigestInfo ::= SEQUENCE { 156 | * digestAlgorithm DigestAlgorithmIdentifier, 157 | * digest Digest } 158 | * 159 | * DigestAlgorithmIdentifier ::= AlgorithmIdentifier 160 | * 161 | * Digest ::= OCTET STRING 162 | */ 163 | #define ASN1_HASH_MDX \ 164 | ( \ 165 | ASN1_STR_CONSTRUCTED_SEQUENCE "\x20" \ 166 | ASN1_STR_CONSTRUCTED_SEQUENCE "\x0C" \ 167 | ASN1_STR_OID "\x08" \ 168 | OID_DIGEST_ALG_MDX \ 169 | ASN1_STR_NULL "\x00" \ 170 | ASN1_STR_OCTET_STRING "\x10" \ 171 | ) 172 | 173 | #define ASN1_HASH_SHA1 \ 174 | ASN1_STR_CONSTRUCTED_SEQUENCE "\x21" \ 175 | ASN1_STR_CONSTRUCTED_SEQUENCE "\x09" \ 176 | ASN1_STR_OID "\x05" \ 177 | OID_HASH_ALG_SHA1 \ 178 | ASN1_STR_NULL "\x00" \ 179 | ASN1_STR_OCTET_STRING "\x14" 180 | 181 | #define ASN1_HASH_SHA2X \ 182 | ASN1_STR_CONSTRUCTED_SEQUENCE "\x11" \ 183 | ASN1_STR_CONSTRUCTED_SEQUENCE "\x0d" \ 184 | ASN1_STR_OID "\x09" \ 185 | OID_HASH_ALG_SHA2X \ 186 | ASN1_STR_NULL "\x00" \ 187 | ASN1_STR_OCTET_STRING "\x00" 188 | 189 | /** 190 | * \brief RSA context structure 191 | */ 192 | typedef struct 193 | { 194 | int ver; /*!< always 0 */ 195 | int len; /*!< size(N) in chars */ 196 | 197 | mpi N; /*!< public modulus */ 198 | mpi E; /*!< public exponent */ 199 | 200 | mpi D; /*!< private exponent */ 201 | mpi P; /*!< 1st prime factor */ 202 | mpi Q; /*!< 2nd prime factor */ 203 | mpi DP; /*!< D % (P - 1) */ 204 | mpi DQ; /*!< D % (Q - 1) */ 205 | mpi QP; /*!< 1 / (Q % P) */ 206 | 207 | mpi RN; /*!< cached R^2 mod N */ 208 | mpi RP; /*!< cached R^2 mod P */ 209 | mpi RQ; /*!< cached R^2 mod Q */ 210 | 211 | int padding; /*!< 1.5 or OAEP/PSS */ 212 | int hash_id; /*!< hash identifier */ 213 | } 214 | rsa_context; 215 | 216 | #ifdef __cplusplus 217 | extern "C" { 218 | #endif 219 | 220 | /** 221 | * \brief Initialize an RSA context 222 | * 223 | * \param ctx RSA context to be initialized 224 | * \param padding RSA_PKCS_V15 or RSA_PKCS_V21 225 | * \param hash_id RSA_PKCS_V21 hash identifier 226 | * 227 | * \note The hash_id parameter is actually ignored 228 | * when using RSA_PKCS_V15 padding. 229 | * 230 | * \note Currently, RSA_PKCS_V21 padding 231 | * is not supported. 232 | */ 233 | void rsa_init( rsa_context *ctx, 234 | int padding, 235 | int hash_id); 236 | 237 | /** 238 | * \brief Generate an RSA keypair 239 | * 240 | * \param ctx RSA context that will hold the key 241 | * \param f_rng RNG function 242 | * \param p_rng RNG parameter 243 | * \param nbits size of the public key in bits 244 | * \param exponent public exponent (e.g., 65537) 245 | * 246 | * \note rsa_init() must be called beforehand to setup 247 | * the RSA context. 248 | * 249 | * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code 250 | */ 251 | int rsa_gen_key( rsa_context *ctx, 252 | int (*f_rng)(void *), 253 | void *p_rng, 254 | int nbits, int exponent ); 255 | 256 | /** 257 | * \brief Check a public RSA key 258 | * 259 | * \param ctx RSA context to be checked 260 | * 261 | * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code 262 | */ 263 | int rsa_check_pubkey( const rsa_context *ctx ); 264 | 265 | /** 266 | * \brief Check a private RSA key 267 | * 268 | * \param ctx RSA context to be checked 269 | * 270 | * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code 271 | */ 272 | int rsa_check_privkey( const rsa_context *ctx ); 273 | 274 | /** 275 | * \brief Do an RSA public key operation 276 | * 277 | * \param ctx RSA context 278 | * \param input input buffer 279 | * \param output output buffer 280 | * 281 | * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code 282 | * 283 | * \note This function does NOT take care of message 284 | * padding. Also, be sure to set input[0] = 0 or assure that 285 | * input is smaller than N. 286 | * 287 | * \note The input and output buffers must be large 288 | * enough (eg. 128 bytes if RSA-1024 is used). 289 | */ 290 | int rsa_public( rsa_context *ctx, 291 | const unsigned char *input, 292 | unsigned char *output ); 293 | 294 | /** 295 | * \brief Do an RSA private key operation 296 | * 297 | * \param ctx RSA context 298 | * \param input input buffer 299 | * \param output output buffer 300 | * 301 | * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code 302 | * 303 | * \note The input and output buffers must be large 304 | * enough (eg. 128 bytes if RSA-1024 is used). 305 | */ 306 | int rsa_private( rsa_context *ctx, 307 | const unsigned char *input, 308 | unsigned char *output ); 309 | 310 | /** 311 | * \brief Add the message padding, then do an RSA operation 312 | * 313 | * \param ctx RSA context 314 | * \param f_rng RNG function 315 | * \param p_rng RNG parameter 316 | * \param mode RSA_PUBLIC or RSA_PRIVATE 317 | * \param ilen contains the plaintext length 318 | * \param input buffer holding the data to be encrypted 319 | * \param output buffer that will hold the ciphertext 320 | * 321 | * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code 322 | * 323 | * \note The output buffer must be as large as the size 324 | * of ctx->N (eg. 128 bytes if RSA-1024 is used). 325 | */ 326 | int rsa_pkcs1_encrypt( rsa_context *ctx, 327 | int (*f_rng)(void *), 328 | void *p_rng, 329 | int mode, int ilen, 330 | const unsigned char *input, 331 | unsigned char *output ); 332 | 333 | /** 334 | * \brief Do an RSA operation, then remove the message padding 335 | * 336 | * \param ctx RSA context 337 | * \param mode RSA_PUBLIC or RSA_PRIVATE 338 | * \param input buffer holding the encrypted data 339 | * \param output buffer that will hold the plaintext 340 | * \param olen will contain the plaintext length 341 | * \param output_max_len maximum length of the output buffer 342 | * 343 | * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code 344 | * 345 | * \note The output buffer must be as large as the size 346 | * of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise 347 | * an error is thrown. 348 | */ 349 | int rsa_pkcs1_decrypt( rsa_context *ctx, 350 | int mode, int *olen, 351 | const unsigned char *input, 352 | unsigned char *output, 353 | int output_max_len ); 354 | 355 | /** 356 | * \brief Do a private RSA to sign a message digest 357 | * 358 | * \param ctx RSA context 359 | * \param mode RSA_PUBLIC or RSA_PRIVATE 360 | * \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512} 361 | * \param hashlen message digest length (for SIG_RSA_RAW only) 362 | * \param hash buffer holding the message digest 363 | * \param sig buffer that will hold the ciphertext 364 | * 365 | * \return 0 if the signing operation was successful, 366 | * or an POLARSSL_ERR_RSA_XXX error code 367 | * 368 | * \note The "sig" buffer must be as large as the size 369 | * of ctx->N (eg. 128 bytes if RSA-1024 is used). 370 | */ 371 | int rsa_pkcs1_sign( rsa_context *ctx, 372 | int mode, 373 | int hash_id, 374 | int hashlen, 375 | const unsigned char *hash, 376 | unsigned char *sig ); 377 | 378 | /** 379 | * \brief Do a public RSA and check the message digest 380 | * 381 | * \param ctx points to an RSA public key 382 | * \param mode RSA_PUBLIC or RSA_PRIVATE 383 | * \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512} 384 | * \param hashlen message digest length (for SIG_RSA_RAW only) 385 | * \param hash buffer holding the message digest 386 | * \param sig buffer holding the ciphertext 387 | * 388 | * \return 0 if the verify operation was successful, 389 | * or an POLARSSL_ERR_RSA_XXX error code 390 | * 391 | * \note The "sig" buffer must be as large as the size 392 | * of ctx->N (eg. 128 bytes if RSA-1024 is used). 393 | */ 394 | int rsa_pkcs1_verify( rsa_context *ctx, 395 | int mode, 396 | int hash_id, 397 | int hashlen, 398 | const unsigned char *hash, 399 | unsigned char *sig ); 400 | 401 | /** 402 | * \brief Free the components of an RSA key 403 | * 404 | * \param ctx RSA Context to free 405 | */ 406 | void rsa_free( rsa_context *ctx ); 407 | 408 | /* PDKIM declarations (not part of polarssl) */ 409 | int rsa_parse_public_key( rsa_context *rsa, unsigned char *buf, int buflen ); 410 | int rsa_parse_key( rsa_context *rsa, unsigned char *buf, int buflen, 411 | unsigned char *pwd, int pwdlen ); 412 | 413 | 414 | #ifdef __cplusplus 415 | } 416 | #endif 417 | 418 | #endif /* rsa.h */ 419 | -------------------------------------------------------------------------------- /bignum.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file bignum.h 3 | * 4 | * Copyright (C) 2006-2010, Brainspark B.V. 5 | * 6 | * This file is part of PolarSSL (http://www.polarssl.org) 7 | * Lead Maintainer: Paul Bakker 8 | * 9 | * All rights reserved. 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; if not, write to the Free Software Foundation, Inc., 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 24 | */ 25 | #ifndef POLARSSL_BIGNUM_H 26 | #define POLARSSL_BIGNUM_H 27 | 28 | #include 29 | 30 | #define POLARSSL_ERR_MPI_FILE_IO_ERROR 0x0002 31 | #define POLARSSL_ERR_MPI_BAD_INPUT_DATA 0x0004 32 | #define POLARSSL_ERR_MPI_INVALID_CHARACTER 0x0006 33 | #define POLARSSL_ERR_MPI_BUFFER_TOO_SMALL 0x0008 34 | #define POLARSSL_ERR_MPI_NEGATIVE_VALUE 0x000A 35 | #define POLARSSL_ERR_MPI_DIVISION_BY_ZERO 0x000C 36 | #define POLARSSL_ERR_MPI_NOT_ACCEPTABLE 0x000E 37 | 38 | #define MPI_CHK(f) if( ( ret = f ) != 0 ) goto cleanup 39 | 40 | /* 41 | * Define the base integer type, architecture-wise 42 | */ 43 | #if defined(POLARSSL_HAVE_INT8) 44 | typedef unsigned char t_int; 45 | typedef unsigned short t_dbl; 46 | #else 47 | #if defined(POLARSSL_HAVE_INT16) 48 | typedef unsigned short t_int; 49 | typedef unsigned long t_dbl; 50 | #else 51 | typedef unsigned long t_int; 52 | #if defined(_MSC_VER) && defined(_M_IX86) 53 | typedef unsigned __int64 t_dbl; 54 | #else 55 | #if defined(__amd64__) || defined(__x86_64__) || \ 56 | defined(__ppc64__) || defined(__powerpc64__) || \ 57 | defined(__ia64__) || defined(__alpha__) 58 | typedef unsigned int t_dbl __attribute__((mode(TI))); 59 | #else 60 | #if defined(POLARSSL_HAVE_LONGLONG) 61 | typedef unsigned long long t_dbl; 62 | #endif 63 | #endif 64 | #endif 65 | #endif 66 | #endif 67 | 68 | /** 69 | * \brief MPI structure 70 | */ 71 | typedef struct 72 | { 73 | int s; /*!< integer sign */ 74 | int n; /*!< total # of limbs */ 75 | t_int *p; /*!< pointer to limbs */ 76 | } 77 | mpi; 78 | 79 | #ifdef __cplusplus 80 | extern "C" { 81 | #endif 82 | 83 | /** 84 | * \brief Initialize one or more mpi 85 | */ 86 | void mpi_init( mpi *X, ... ); 87 | 88 | /** 89 | * \brief Unallocate one or more mpi 90 | */ 91 | void mpi_free( mpi *X, ... ); 92 | 93 | /** 94 | * \brief Enlarge to the specified number of limbs 95 | * 96 | * \param X MPI to grow 97 | * \param nblimbs The target number of limbs 98 | * 99 | * \return 0 if successful, 100 | * 1 if memory allocation failed 101 | */ 102 | int mpi_grow( mpi *X, int nblimbs ); 103 | 104 | /** 105 | * \brief Copy the contents of Y into X 106 | * 107 | * \param X Destination MPI 108 | * \param Y Source MPI 109 | * 110 | * \return 0 if successful, 111 | * 1 if memory allocation failed 112 | */ 113 | int mpi_copy( mpi *X, const mpi *Y ); 114 | 115 | /** 116 | * \brief Swap the contents of X and Y 117 | * 118 | * \param X First MPI value 119 | * \param Y Second MPI value 120 | */ 121 | void mpi_swap( mpi *X, mpi *Y ); 122 | 123 | /** 124 | * \brief Set value from integer 125 | * 126 | * \param X MPI to set 127 | * \param z Value to use 128 | * 129 | * \return 0 if successful, 130 | * 1 if memory allocation failed 131 | */ 132 | int mpi_lset( mpi *X, int z ); 133 | 134 | /** 135 | * \brief Return the number of least significant bits 136 | * 137 | * \param X MPI to use 138 | */ 139 | int mpi_lsb( const mpi *X ); 140 | 141 | /** 142 | * \brief Return the number of most significant bits 143 | * 144 | * \param X MPI to use 145 | */ 146 | int mpi_msb( const mpi *X ); 147 | 148 | /** 149 | * \brief Return the total size in bytes 150 | * 151 | * \param X MPI to use 152 | */ 153 | int mpi_size( const mpi *X ); 154 | 155 | /** 156 | * \brief Import from an ASCII string 157 | * 158 | * \param X Destination MPI 159 | * \param radix Input numeric base 160 | * \param s Null-terminated string buffer 161 | * 162 | * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code 163 | */ 164 | int mpi_read_string( mpi *X, int radix, const char *s ); 165 | 166 | /** 167 | * \brief Export into an ASCII string 168 | * 169 | * \param X Source MPI 170 | * \param radix Output numeric base 171 | * \param s String buffer 172 | * \param slen String buffer size 173 | * 174 | * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code. 175 | * *slen is always updated to reflect the amount 176 | * of data that has (or would have) been written. 177 | * 178 | * \note Call this function with *slen = 0 to obtain the 179 | * minimum required buffer size in *slen. 180 | */ 181 | int mpi_write_string( const mpi *X, int radix, char *s, int *slen ); 182 | 183 | /** 184 | * \brief Read X from an opened file 185 | * 186 | * \param X Destination MPI 187 | * \param radix Input numeric base 188 | * \param fin Input file handle 189 | * 190 | * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code 191 | */ 192 | int mpi_read_file( mpi *X, int radix, FILE *fin ); 193 | 194 | /** 195 | * \brief Write X into an opened file, or stdout if fout is NULL 196 | * 197 | * \param p Prefix, can be NULL 198 | * \param X Source MPI 199 | * \param radix Output numeric base 200 | * \param fout Output file handle (can be NULL) 201 | * 202 | * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code 203 | * 204 | * \note Set fout == NULL to print X on the console. 205 | */ 206 | int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout ); 207 | 208 | /** 209 | * \brief Import X from unsigned binary data, big endian 210 | * 211 | * \param X Destination MPI 212 | * \param buf Input buffer 213 | * \param buflen Input buffer size 214 | * 215 | * \return 0 if successful, 216 | * 1 if memory allocation failed 217 | */ 218 | int mpi_read_binary( mpi *X, const unsigned char *buf, int buflen ); 219 | 220 | /** 221 | * \brief Export X into unsigned binary data, big endian 222 | * 223 | * \param X Source MPI 224 | * \param buf Output buffer 225 | * \param buflen Output buffer size 226 | * 227 | * \return 0 if successful, 228 | * POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough 229 | */ 230 | int mpi_write_binary( const mpi *X, unsigned char *buf, int buflen ); 231 | 232 | /** 233 | * \brief Left-shift: X <<= count 234 | * 235 | * \param X MPI to shift 236 | * \param count Amount to shift 237 | * 238 | * \return 0 if successful, 239 | * 1 if memory allocation failed 240 | */ 241 | int mpi_shift_l( mpi *X, int count ); 242 | 243 | /** 244 | * \brief Right-shift: X >>= count 245 | * 246 | * \param X MPI to shift 247 | * \param count Amount to shift 248 | * 249 | * \return 0 if successful, 250 | * 1 if memory allocation failed 251 | */ 252 | int mpi_shift_r( mpi *X, int count ); 253 | 254 | /** 255 | * \brief Compare unsigned values 256 | * 257 | * \param X Left-hand MPI 258 | * \param Y Right-hand MPI 259 | * 260 | * \return 1 if |X| is greater than |Y|, 261 | * -1 if |X| is lesser than |Y| or 262 | * 0 if |X| is equal to |Y| 263 | */ 264 | int mpi_cmp_abs( const mpi *X, const mpi *Y ); 265 | 266 | /** 267 | * \brief Compare signed values 268 | * 269 | * \param X Left-hand MPI 270 | * \param Y Right-hand MPI 271 | * 272 | * \return 1 if X is greater than Y, 273 | * -1 if X is lesser than Y or 274 | * 0 if X is equal to Y 275 | */ 276 | int mpi_cmp_mpi( const mpi *X, const mpi *Y ); 277 | 278 | /** 279 | * \brief Compare signed values 280 | * 281 | * \param X Left-hand MPI 282 | * \param z The integer value to compare to 283 | * 284 | * \return 1 if X is greater than z, 285 | * -1 if X is lesser than z or 286 | * 0 if X is equal to z 287 | */ 288 | int mpi_cmp_int( const mpi *X, int z ); 289 | 290 | /** 291 | * \brief Unsigned addition: X = |A| + |B| 292 | * 293 | * \param X Destination MPI 294 | * \param A Left-hand MPI 295 | * \param B Right-hand MPI 296 | * 297 | * \return 0 if successful, 298 | * 1 if memory allocation failed 299 | */ 300 | int mpi_add_abs( mpi *X, const mpi *A, const mpi *B ); 301 | 302 | /** 303 | * \brief Unsigned substraction: X = |A| - |B| 304 | * 305 | * \param X Destination MPI 306 | * \param A Left-hand MPI 307 | * \param B Right-hand MPI 308 | * 309 | * \return 0 if successful, 310 | * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B is greater than A 311 | */ 312 | int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B ); 313 | 314 | /** 315 | * \brief Signed addition: X = A + B 316 | * 317 | * \param X Destination MPI 318 | * \param A Left-hand MPI 319 | * \param B Right-hand MPI 320 | * 321 | * \return 0 if successful, 322 | * 1 if memory allocation failed 323 | */ 324 | int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B ); 325 | 326 | /** 327 | * \brief Signed substraction: X = A - B 328 | * 329 | * \param X Destination MPI 330 | * \param A Left-hand MPI 331 | * \param B Right-hand MPI 332 | * 333 | * \return 0 if successful, 334 | * 1 if memory allocation failed 335 | */ 336 | int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B ); 337 | 338 | /** 339 | * \brief Signed addition: X = A + b 340 | * 341 | * \param X Destination MPI 342 | * \param A Left-hand MPI 343 | * \param b The integer value to add 344 | * 345 | * \return 0 if successful, 346 | * 1 if memory allocation failed 347 | */ 348 | int mpi_add_int( mpi *X, const mpi *A, int b ); 349 | 350 | /** 351 | * \brief Signed substraction: X = A - b 352 | * 353 | * \param X Destination MPI 354 | * \param A Left-hand MPI 355 | * \param b The integer value to subtract 356 | * 357 | * \return 0 if successful, 358 | * 1 if memory allocation failed 359 | */ 360 | int mpi_sub_int( mpi *X, const mpi *A, int b ); 361 | 362 | /** 363 | * \brief Baseline multiplication: X = A * B 364 | * 365 | * \param X Destination MPI 366 | * \param A Left-hand MPI 367 | * \param B Right-hand MPI 368 | * 369 | * \return 0 if successful, 370 | * 1 if memory allocation failed 371 | */ 372 | int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B ); 373 | 374 | /** 375 | * \brief Baseline multiplication: X = A * b 376 | * Note: b is an unsigned integer type, thus 377 | * Negative values of b are ignored. 378 | * 379 | * \param X Destination MPI 380 | * \param A Left-hand MPI 381 | * \param b The integer value to multiply with 382 | * 383 | * \return 0 if successful, 384 | * 1 if memory allocation failed 385 | */ 386 | int mpi_mul_int( mpi *X, const mpi *A, t_int b ); 387 | 388 | /** 389 | * \brief Division by mpi: A = Q * B + R 390 | * 391 | * \param Q Destination MPI for the quotient 392 | * \param R Destination MPI for the rest value 393 | * \param A Left-hand MPI 394 | * \param B Right-hand MPI 395 | * 396 | * \return 0 if successful, 397 | * 1 if memory allocation failed, 398 | * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0 399 | * 400 | * \note Either Q or R can be NULL. 401 | */ 402 | int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B ); 403 | 404 | /** 405 | * \brief Division by int: A = Q * b + R 406 | * 407 | * \param Q Destination MPI for the quotient 408 | * \param R Destination MPI for the rest value 409 | * \param A Left-hand MPI 410 | * \param b Integer to divide by 411 | * 412 | * \return 0 if successful, 413 | * 1 if memory allocation failed, 414 | * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0 415 | * 416 | * \note Either Q or R can be NULL. 417 | */ 418 | int mpi_div_int( mpi *Q, mpi *R, const mpi *A, int b ); 419 | 420 | /** 421 | * \brief Modulo: R = A mod B 422 | * 423 | * \param R Destination MPI for the rest value 424 | * \param A Left-hand MPI 425 | * \param B Right-hand MPI 426 | * 427 | * \return 0 if successful, 428 | * 1 if memory allocation failed, 429 | * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0, 430 | * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B < 0 431 | */ 432 | int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B ); 433 | 434 | /** 435 | * \brief Modulo: r = A mod b 436 | * 437 | * \param r Destination t_int 438 | * \param A Left-hand MPI 439 | * \param b Integer to divide by 440 | * 441 | * \return 0 if successful, 442 | * 1 if memory allocation failed, 443 | * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0, 444 | * POLARSSL_ERR_MPI_NEGATIVE_VALUE if b < 0 445 | */ 446 | int mpi_mod_int( t_int *r, const mpi *A, int b ); 447 | 448 | /** 449 | * \brief Sliding-window exponentiation: X = A^E mod N 450 | * 451 | * \param X Destination MPI 452 | * \param A Left-hand MPI 453 | * \param E Exponent MPI 454 | * \param N Modular MPI 455 | * \param _RR Speed-up MPI used for recalculations 456 | * 457 | * \return 0 if successful, 458 | * 1 if memory allocation failed, 459 | * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or even 460 | * 461 | * \note _RR is used to avoid re-computing R*R mod N across 462 | * multiple calls, which speeds up things a bit. It can 463 | * be set to NULL if the extra performance is unneeded. 464 | */ 465 | int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR ); 466 | 467 | /** 468 | * \brief Greatest common divisor: G = gcd(A, B) 469 | * 470 | * \param G Destination MPI 471 | * \param A Left-hand MPI 472 | * \param B Right-hand MPI 473 | * 474 | * \return 0 if successful, 475 | * 1 if memory allocation failed 476 | */ 477 | int mpi_gcd( mpi *G, const mpi *A, const mpi *B ); 478 | 479 | /** 480 | * \brief Modular inverse: X = A^-1 mod N 481 | * 482 | * \param X Destination MPI 483 | * \param A Left-hand MPI 484 | * \param N Right-hand MPI 485 | * 486 | * \return 0 if successful, 487 | * 1 if memory allocation failed, 488 | * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or nil 489 | POLARSSL_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N 490 | */ 491 | int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N ); 492 | 493 | /** 494 | * \brief Miller-Rabin primality test 495 | * 496 | * \param X MPI to check 497 | * \param f_rng RNG function 498 | * \param p_rng RNG parameter 499 | * 500 | * \return 0 if successful (probably prime), 501 | * 1 if memory allocation failed, 502 | * POLARSSL_ERR_MPI_NOT_ACCEPTABLE if X is not prime 503 | */ 504 | int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng ); 505 | 506 | /** 507 | * \brief Prime number generation 508 | * 509 | * \param X Destination MPI 510 | * \param nbits Required size of X in bits 511 | * \param dh_flag If 1, then (X-1)/2 will be prime too 512 | * \param f_rng RNG function 513 | * \param p_rng RNG parameter 514 | * 515 | * \return 0 if successful (probably prime), 516 | * 1 if memory allocation failed, 517 | * POLARSSL_ERR_MPI_BAD_INPUT_DATA if nbits is < 3 518 | */ 519 | int mpi_gen_prime( mpi *X, int nbits, int dh_flag, 520 | int (*f_rng)(void *), void *p_rng ); 521 | 522 | #ifdef __cplusplus 523 | } 524 | #endif 525 | 526 | #endif /* bignum.h */ 527 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /rsa.c: -------------------------------------------------------------------------------- 1 | /* 2 | * The RSA public-key cryptosystem 3 | * 4 | * Copyright (C) 2006-2010, Brainspark B.V. 5 | * 6 | * This file is part of PolarSSL (http://www.polarssl.org) 7 | * Lead Maintainer: Paul Bakker 8 | * 9 | * All rights reserved. 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; if not, write to the Free Software Foundation, Inc., 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 24 | */ 25 | /* 26 | * RSA was designed by Ron Rivest, Adi Shamir and Len Adleman. 27 | * 28 | * http://theory.lcs.mit.edu/~rivest/rsapaper.pdf 29 | * http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf 30 | */ 31 | 32 | #include "rsa.h" 33 | #include "base64.h" 34 | 35 | #include 36 | #include 37 | #include 38 | 39 | 40 | 41 | /* *************** begin copy from x509parse.c ********************/ 42 | /* 43 | * ASN.1 DER decoding routines 44 | */ 45 | static int asn1_get_len( unsigned char **p, 46 | const unsigned char *end, 47 | int *len ) 48 | { 49 | if( ( end - *p ) < 1 ) 50 | return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); 51 | 52 | if( ( **p & 0x80 ) == 0 ) 53 | *len = *(*p)++; 54 | else 55 | { 56 | switch( **p & 0x7F ) 57 | { 58 | case 1: 59 | if( ( end - *p ) < 2 ) 60 | return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); 61 | 62 | *len = (*p)[1]; 63 | (*p) += 2; 64 | break; 65 | 66 | case 2: 67 | if( ( end - *p ) < 3 ) 68 | return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); 69 | 70 | *len = ( (*p)[1] << 8 ) | (*p)[2]; 71 | (*p) += 3; 72 | break; 73 | 74 | default: 75 | return( POLARSSL_ERR_ASN1_INVALID_LENGTH ); 76 | break; 77 | } 78 | } 79 | 80 | if( *len > (int) ( end - *p ) ) 81 | return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); 82 | 83 | return( 0 ); 84 | } 85 | 86 | static int asn1_get_tag( unsigned char **p, 87 | const unsigned char *end, 88 | int *len, int tag ) 89 | { 90 | if( ( end - *p ) < 1 ) 91 | return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); 92 | 93 | if( **p != tag ) 94 | return( POLARSSL_ERR_ASN1_UNEXPECTED_TAG ); 95 | 96 | (*p)++; 97 | 98 | return( asn1_get_len( p, end, len ) ); 99 | } 100 | 101 | static int asn1_get_int( unsigned char **p, 102 | const unsigned char *end, 103 | int *val ) 104 | { 105 | int ret, len; 106 | 107 | if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 ) 108 | return( ret ); 109 | 110 | if( len > (int) sizeof( int ) || ( **p & 0x80 ) != 0 ) 111 | return( POLARSSL_ERR_ASN1_INVALID_LENGTH ); 112 | 113 | *val = 0; 114 | 115 | while( len-- > 0 ) 116 | { 117 | *val = ( *val << 8 ) | **p; 118 | (*p)++; 119 | } 120 | 121 | return( 0 ); 122 | } 123 | 124 | static int asn1_get_mpi( unsigned char **p, 125 | const unsigned char *end, 126 | mpi *X ) 127 | { 128 | int ret, len; 129 | 130 | if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 ) 131 | return( ret ); 132 | 133 | ret = mpi_read_binary( X, *p, len ); 134 | 135 | *p += len; 136 | 137 | return( ret ); 138 | } 139 | /* *************** end copy from x509parse.c ********************/ 140 | 141 | 142 | 143 | 144 | /* 145 | * Initialize an RSA context 146 | */ 147 | void rsa_init( rsa_context *ctx, 148 | int padding, 149 | int hash_id ) 150 | { 151 | memset( ctx, 0, sizeof( rsa_context ) ); 152 | 153 | ctx->padding = padding; 154 | ctx->hash_id = hash_id; 155 | } 156 | 157 | #if defined(POLARSSL_GENPRIME) 158 | 159 | /* 160 | * Generate an RSA keypair 161 | */ 162 | int rsa_gen_key( rsa_context *ctx, 163 | int (*f_rng)(void *), 164 | void *p_rng, 165 | int nbits, int exponent ) 166 | { 167 | int ret; 168 | mpi P1, Q1, H, G; 169 | 170 | if( f_rng == NULL || nbits < 128 || exponent < 3 ) 171 | return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); 172 | 173 | mpi_init( &P1, &Q1, &H, &G, NULL ); 174 | 175 | /* 176 | * find primes P and Q with Q < P so that: 177 | * GCD( E, (P-1)*(Q-1) ) == 1 178 | */ 179 | MPI_CHK( mpi_lset( &ctx->E, exponent ) ); 180 | 181 | do 182 | { 183 | MPI_CHK( mpi_gen_prime( &ctx->P, ( nbits + 1 ) >> 1, 0, 184 | f_rng, p_rng ) ); 185 | 186 | MPI_CHK( mpi_gen_prime( &ctx->Q, ( nbits + 1 ) >> 1, 0, 187 | f_rng, p_rng ) ); 188 | 189 | if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 ) 190 | mpi_swap( &ctx->P, &ctx->Q ); 191 | 192 | if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 ) 193 | continue; 194 | 195 | MPI_CHK( mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) ); 196 | if( mpi_msb( &ctx->N ) != nbits ) 197 | continue; 198 | 199 | MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) ); 200 | MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) ); 201 | MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) ); 202 | MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) ); 203 | } 204 | while( mpi_cmp_int( &G, 1 ) != 0 ); 205 | 206 | /* 207 | * D = E^-1 mod ((P-1)*(Q-1)) 208 | * DP = D mod (P - 1) 209 | * DQ = D mod (Q - 1) 210 | * QP = Q^-1 mod P 211 | */ 212 | MPI_CHK( mpi_inv_mod( &ctx->D , &ctx->E, &H ) ); 213 | MPI_CHK( mpi_mod_mpi( &ctx->DP, &ctx->D, &P1 ) ); 214 | MPI_CHK( mpi_mod_mpi( &ctx->DQ, &ctx->D, &Q1 ) ); 215 | MPI_CHK( mpi_inv_mod( &ctx->QP, &ctx->Q, &ctx->P ) ); 216 | 217 | ctx->len = ( mpi_msb( &ctx->N ) + 7 ) >> 3; 218 | 219 | cleanup: 220 | 221 | mpi_free( &G, &H, &Q1, &P1, NULL ); 222 | 223 | if( ret != 0 ) 224 | { 225 | rsa_free( ctx ); 226 | return( POLARSSL_ERR_RSA_KEY_GEN_FAILED | ret ); 227 | } 228 | 229 | return( 0 ); 230 | } 231 | 232 | #endif 233 | 234 | /* 235 | * Check a public RSA key 236 | */ 237 | int rsa_check_pubkey( const rsa_context *ctx ) 238 | { 239 | if( !ctx->N.p || !ctx->E.p ) 240 | return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED ); 241 | 242 | if( ( ctx->N.p[0] & 1 ) == 0 || 243 | ( ctx->E.p[0] & 1 ) == 0 ) 244 | return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED ); 245 | 246 | if( mpi_msb( &ctx->N ) < 128 || 247 | mpi_msb( &ctx->N ) > 4096 ) 248 | return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED ); 249 | 250 | if( mpi_msb( &ctx->E ) < 2 || 251 | mpi_msb( &ctx->E ) > 64 ) 252 | return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED ); 253 | 254 | return( 0 ); 255 | } 256 | 257 | /* 258 | * Check a private RSA key 259 | */ 260 | int rsa_check_privkey( const rsa_context *ctx ) 261 | { 262 | int ret; 263 | mpi PQ, DE, P1, Q1, H, I, G, G2, L1, L2; 264 | 265 | if( ( ret = rsa_check_pubkey( ctx ) ) != 0 ) 266 | return( ret ); 267 | 268 | if( !ctx->P.p || !ctx->Q.p || !ctx->D.p ) 269 | return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED ); 270 | 271 | mpi_init( &PQ, &DE, &P1, &Q1, &H, &I, &G, &G2, &L1, &L2, NULL ); 272 | 273 | MPI_CHK( mpi_mul_mpi( &PQ, &ctx->P, &ctx->Q ) ); 274 | MPI_CHK( mpi_mul_mpi( &DE, &ctx->D, &ctx->E ) ); 275 | MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) ); 276 | MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) ); 277 | MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) ); 278 | MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) ); 279 | 280 | MPI_CHK( mpi_gcd( &G2, &P1, &Q1 ) ); 281 | MPI_CHK( mpi_div_mpi( &L1, &L2, &H, &G2 ) ); 282 | MPI_CHK( mpi_mod_mpi( &I, &DE, &L1 ) ); 283 | 284 | /* 285 | * Check for a valid PKCS1v2 private key 286 | */ 287 | if( mpi_cmp_mpi( &PQ, &ctx->N ) == 0 && 288 | mpi_cmp_int( &L2, 0 ) == 0 && 289 | mpi_cmp_int( &I, 1 ) == 0 && 290 | mpi_cmp_int( &G, 1 ) == 0 ) 291 | { 292 | mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, &G2, &L1, &L2, NULL ); 293 | return( 0 ); 294 | } 295 | 296 | 297 | cleanup: 298 | 299 | mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, &G2, &L1, &L2, NULL ); 300 | return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED | ret ); 301 | } 302 | 303 | /* 304 | * Do an RSA public key operation 305 | */ 306 | int rsa_public( rsa_context *ctx, 307 | const unsigned char *input, 308 | unsigned char *output ) 309 | { 310 | int ret, olen; 311 | mpi T; 312 | 313 | mpi_init( &T, NULL ); 314 | 315 | MPI_CHK( mpi_read_binary( &T, input, ctx->len ) ); 316 | 317 | if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 ) 318 | { 319 | mpi_free( &T, NULL ); 320 | return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); 321 | } 322 | 323 | olen = ctx->len; 324 | MPI_CHK( mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) ); 325 | MPI_CHK( mpi_write_binary( &T, output, olen ) ); 326 | 327 | cleanup: 328 | 329 | mpi_free( &T, NULL ); 330 | 331 | if( ret != 0 ) 332 | return( POLARSSL_ERR_RSA_PUBLIC_FAILED | ret ); 333 | 334 | return( 0 ); 335 | } 336 | 337 | /* 338 | * Do an RSA private key operation 339 | */ 340 | int rsa_private( rsa_context *ctx, 341 | const unsigned char *input, 342 | unsigned char *output ) 343 | { 344 | int ret, olen; 345 | mpi T, T1, T2; 346 | 347 | mpi_init( &T, &T1, &T2, NULL ); 348 | 349 | MPI_CHK( mpi_read_binary( &T, input, ctx->len ) ); 350 | 351 | if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 ) 352 | { 353 | mpi_free( &T, NULL ); 354 | return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); 355 | } 356 | 357 | #if 0 358 | MPI_CHK( mpi_exp_mod( &T, &T, &ctx->D, &ctx->N, &ctx->RN ) ); 359 | #else 360 | /* 361 | * faster decryption using the CRT 362 | * 363 | * T1 = input ^ dP mod P 364 | * T2 = input ^ dQ mod Q 365 | */ 366 | MPI_CHK( mpi_exp_mod( &T1, &T, &ctx->DP, &ctx->P, &ctx->RP ) ); 367 | MPI_CHK( mpi_exp_mod( &T2, &T, &ctx->DQ, &ctx->Q, &ctx->RQ ) ); 368 | 369 | /* 370 | * T = (T1 - T2) * (Q^-1 mod P) mod P 371 | */ 372 | MPI_CHK( mpi_sub_mpi( &T, &T1, &T2 ) ); 373 | MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->QP ) ); 374 | MPI_CHK( mpi_mod_mpi( &T, &T1, &ctx->P ) ); 375 | 376 | /* 377 | * output = T2 + T * Q 378 | */ 379 | MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->Q ) ); 380 | MPI_CHK( mpi_add_mpi( &T, &T2, &T1 ) ); 381 | #endif 382 | 383 | olen = ctx->len; 384 | MPI_CHK( mpi_write_binary( &T, output, olen ) ); 385 | 386 | cleanup: 387 | 388 | mpi_free( &T, &T1, &T2, NULL ); 389 | 390 | if( ret != 0 ) 391 | return( POLARSSL_ERR_RSA_PRIVATE_FAILED | ret ); 392 | 393 | return( 0 ); 394 | } 395 | 396 | /* 397 | * Add the message padding, then do an RSA operation 398 | */ 399 | int rsa_pkcs1_encrypt( rsa_context *ctx, 400 | int (*f_rng)(void *), 401 | void *p_rng, 402 | int mode, int ilen, 403 | const unsigned char *input, 404 | unsigned char *output ) 405 | { 406 | int nb_pad, olen; 407 | unsigned char *p = output; 408 | 409 | olen = ctx->len; 410 | 411 | switch( ctx->padding ) 412 | { 413 | case RSA_PKCS_V15: 414 | 415 | if( ilen < 0 || olen < ilen + 11 || f_rng == NULL ) 416 | return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); 417 | 418 | nb_pad = olen - 3 - ilen; 419 | 420 | *p++ = 0; 421 | *p++ = RSA_CRYPT; 422 | 423 | while( nb_pad-- > 0 ) 424 | { 425 | int rng_dl = 100; 426 | 427 | do { 428 | *p = (unsigned char) f_rng( p_rng ); 429 | } while( *p == 0 && --rng_dl ); 430 | 431 | // Check if RNG failed to generate data 432 | // 433 | if( rng_dl == 0 ) 434 | return POLARSSL_ERR_RSA_RNG_FAILED; 435 | 436 | p++; 437 | } 438 | *p++ = 0; 439 | memcpy( p, input, ilen ); 440 | break; 441 | 442 | default: 443 | 444 | return( POLARSSL_ERR_RSA_INVALID_PADDING ); 445 | } 446 | 447 | return( ( mode == RSA_PUBLIC ) 448 | ? rsa_public( ctx, output, output ) 449 | : rsa_private( ctx, output, output ) ); 450 | } 451 | 452 | /* 453 | * Do an RSA operation, then remove the message padding 454 | */ 455 | int rsa_pkcs1_decrypt( rsa_context *ctx, 456 | int mode, int *olen, 457 | const unsigned char *input, 458 | unsigned char *output, 459 | int output_max_len) 460 | { 461 | int ret, ilen; 462 | unsigned char *p; 463 | unsigned char buf[1024]; 464 | 465 | ilen = ctx->len; 466 | 467 | if( ilen < 16 || ilen > (int) sizeof( buf ) ) 468 | return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); 469 | 470 | ret = ( mode == RSA_PUBLIC ) 471 | ? rsa_public( ctx, input, buf ) 472 | : rsa_private( ctx, input, buf ); 473 | 474 | if( ret != 0 ) 475 | return( ret ); 476 | 477 | p = buf; 478 | 479 | switch( ctx->padding ) 480 | { 481 | case RSA_PKCS_V15: 482 | 483 | if( *p++ != 0 || *p++ != RSA_CRYPT ) 484 | return( POLARSSL_ERR_RSA_INVALID_PADDING ); 485 | 486 | while( *p != 0 ) 487 | { 488 | if( p >= buf + ilen - 1 ) 489 | return( POLARSSL_ERR_RSA_INVALID_PADDING ); 490 | p++; 491 | } 492 | p++; 493 | break; 494 | 495 | default: 496 | 497 | return( POLARSSL_ERR_RSA_INVALID_PADDING ); 498 | } 499 | 500 | if (ilen - (int)(p - buf) > output_max_len) 501 | return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE ); 502 | 503 | *olen = ilen - (int)(p - buf); 504 | memcpy( output, p, *olen ); 505 | 506 | return( 0 ); 507 | } 508 | 509 | /* 510 | * Do an RSA operation to sign the message digest 511 | */ 512 | int rsa_pkcs1_sign( rsa_context *ctx, 513 | int mode, 514 | int hash_id, 515 | int hashlen, 516 | const unsigned char *hash, 517 | unsigned char *sig ) 518 | { 519 | int nb_pad, olen; 520 | unsigned char *p = sig; 521 | 522 | olen = ctx->len; 523 | 524 | switch( ctx->padding ) 525 | { 526 | case RSA_PKCS_V15: 527 | 528 | switch( hash_id ) 529 | { 530 | case SIG_RSA_RAW: 531 | nb_pad = olen - 3 - hashlen; 532 | break; 533 | 534 | case SIG_RSA_MD2: 535 | case SIG_RSA_MD4: 536 | case SIG_RSA_MD5: 537 | nb_pad = olen - 3 - 34; 538 | break; 539 | 540 | case SIG_RSA_SHA1: 541 | nb_pad = olen - 3 - 35; 542 | break; 543 | 544 | case SIG_RSA_SHA224: 545 | nb_pad = olen - 3 - 47; 546 | break; 547 | 548 | case SIG_RSA_SHA256: 549 | nb_pad = olen - 3 - 51; 550 | break; 551 | 552 | case SIG_RSA_SHA384: 553 | nb_pad = olen - 3 - 67; 554 | break; 555 | 556 | case SIG_RSA_SHA512: 557 | nb_pad = olen - 3 - 83; 558 | break; 559 | 560 | 561 | default: 562 | return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); 563 | } 564 | 565 | if( nb_pad < 8 ) 566 | return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); 567 | 568 | *p++ = 0; 569 | *p++ = RSA_SIGN; 570 | memset( p, 0xFF, nb_pad ); 571 | p += nb_pad; 572 | *p++ = 0; 573 | break; 574 | 575 | default: 576 | 577 | return( POLARSSL_ERR_RSA_INVALID_PADDING ); 578 | } 579 | 580 | switch( hash_id ) 581 | { 582 | case SIG_RSA_RAW: 583 | memcpy( p, hash, hashlen ); 584 | break; 585 | 586 | case SIG_RSA_MD2: 587 | memcpy( p, ASN1_HASH_MDX, 18 ); 588 | memcpy( p + 18, hash, 16 ); 589 | p[13] = 2; break; 590 | 591 | case SIG_RSA_MD4: 592 | memcpy( p, ASN1_HASH_MDX, 18 ); 593 | memcpy( p + 18, hash, 16 ); 594 | p[13] = 4; break; 595 | 596 | case SIG_RSA_MD5: 597 | memcpy( p, ASN1_HASH_MDX, 18 ); 598 | memcpy( p + 18, hash, 16 ); 599 | p[13] = 5; break; 600 | 601 | case SIG_RSA_SHA1: 602 | memcpy( p, ASN1_HASH_SHA1, 15 ); 603 | memcpy( p + 15, hash, 20 ); 604 | break; 605 | 606 | case SIG_RSA_SHA224: 607 | memcpy( p, ASN1_HASH_SHA2X, 19 ); 608 | memcpy( p + 19, hash, 28 ); 609 | p[1] += 28; p[14] = 4; p[18] += 28; break; 610 | 611 | case SIG_RSA_SHA256: 612 | memcpy( p, ASN1_HASH_SHA2X, 19 ); 613 | memcpy( p + 19, hash, 32 ); 614 | p[1] += 32; p[14] = 1; p[18] += 32; break; 615 | 616 | case SIG_RSA_SHA384: 617 | memcpy( p, ASN1_HASH_SHA2X, 19 ); 618 | memcpy( p + 19, hash, 48 ); 619 | p[1] += 48; p[14] = 2; p[18] += 48; break; 620 | 621 | case SIG_RSA_SHA512: 622 | memcpy( p, ASN1_HASH_SHA2X, 19 ); 623 | memcpy( p + 19, hash, 64 ); 624 | p[1] += 64; p[14] = 3; p[18] += 64; break; 625 | 626 | default: 627 | return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); 628 | } 629 | 630 | return( ( mode == RSA_PUBLIC ) 631 | ? rsa_public( ctx, sig, sig ) 632 | : rsa_private( ctx, sig, sig ) ); 633 | } 634 | 635 | /* 636 | * Do an RSA operation and check the message digest 637 | */ 638 | int rsa_pkcs1_verify( rsa_context *ctx, 639 | int mode, 640 | int hash_id, 641 | int hashlen, 642 | const unsigned char *hash, 643 | unsigned char *sig ) 644 | { 645 | int ret, len, siglen; 646 | unsigned char *p, c; 647 | unsigned char buf[1024]; 648 | 649 | siglen = ctx->len; 650 | 651 | if( siglen < 16 || siglen > (int) sizeof( buf ) ) 652 | return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); 653 | 654 | ret = ( mode == RSA_PUBLIC ) 655 | ? rsa_public( ctx, sig, buf ) 656 | : rsa_private( ctx, sig, buf ); 657 | 658 | if( ret != 0 ) 659 | return( ret ); 660 | 661 | p = buf; 662 | 663 | switch( ctx->padding ) 664 | { 665 | case RSA_PKCS_V15: 666 | 667 | if( *p++ != 0 || *p++ != RSA_SIGN ) 668 | return( POLARSSL_ERR_RSA_INVALID_PADDING ); 669 | 670 | while( *p != 0 ) 671 | { 672 | if( p >= buf + siglen - 1 || *p != 0xFF ) 673 | return( POLARSSL_ERR_RSA_INVALID_PADDING ); 674 | p++; 675 | } 676 | p++; 677 | break; 678 | 679 | default: 680 | 681 | return( POLARSSL_ERR_RSA_INVALID_PADDING ); 682 | } 683 | 684 | len = siglen - (int)( p - buf ); 685 | 686 | if( len == 34 ) 687 | { 688 | c = p[13]; 689 | p[13] = 0; 690 | 691 | if( memcmp( p, ASN1_HASH_MDX, 18 ) != 0 ) 692 | return( POLARSSL_ERR_RSA_VERIFY_FAILED ); 693 | 694 | if( ( c == 2 && hash_id == SIG_RSA_MD2 ) || 695 | ( c == 4 && hash_id == SIG_RSA_MD4 ) || 696 | ( c == 5 && hash_id == SIG_RSA_MD5 ) ) 697 | { 698 | if( memcmp( p + 18, hash, 16 ) == 0 ) 699 | return( 0 ); 700 | else 701 | return( POLARSSL_ERR_RSA_VERIFY_FAILED ); 702 | } 703 | } 704 | 705 | if( len == 35 && hash_id == SIG_RSA_SHA1 ) 706 | { 707 | if( memcmp( p, ASN1_HASH_SHA1, 15 ) == 0 && 708 | memcmp( p + 15, hash, 20 ) == 0 ) 709 | return( 0 ); 710 | else 711 | return( POLARSSL_ERR_RSA_VERIFY_FAILED ); 712 | } 713 | if( ( len == 19 + 28 && p[14] == 4 && hash_id == SIG_RSA_SHA224 ) || 714 | ( len == 19 + 32 && p[14] == 1 && hash_id == SIG_RSA_SHA256 ) || 715 | ( len == 19 + 48 && p[14] == 2 && hash_id == SIG_RSA_SHA384 ) || 716 | ( len == 19 + 64 && p[14] == 3 && hash_id == SIG_RSA_SHA512 ) ) 717 | { 718 | c = p[1] - 17; 719 | p[1] = 17; 720 | p[14] = 0; 721 | 722 | if( p[18] == c && 723 | memcmp( p, ASN1_HASH_SHA2X, 18 ) == 0 && 724 | memcmp( p + 19, hash, c ) == 0 ) 725 | return( 0 ); 726 | else 727 | return( POLARSSL_ERR_RSA_VERIFY_FAILED ); 728 | } 729 | 730 | if( len == hashlen && hash_id == SIG_RSA_RAW ) 731 | { 732 | if( memcmp( p, hash, hashlen ) == 0 ) 733 | return( 0 ); 734 | else 735 | return( POLARSSL_ERR_RSA_VERIFY_FAILED ); 736 | } 737 | 738 | return( POLARSSL_ERR_RSA_INVALID_PADDING ); 739 | } 740 | 741 | /* 742 | * Free the components of an RSA key 743 | */ 744 | void rsa_free( rsa_context *ctx ) 745 | { 746 | mpi_free( &ctx->RQ, &ctx->RP, &ctx->RN, 747 | &ctx->QP, &ctx->DQ, &ctx->DP, 748 | &ctx->Q, &ctx->P, &ctx->D, 749 | &ctx->E, &ctx->N, NULL ); 750 | } 751 | 752 | 753 | /* PDKIM code (not copied from polarssl) */ 754 | /* 755 | * Parse a public RSA key 756 | 757 | OpenSSL RSA public key ASN1 container 758 | 0:d=0 hl=3 l= 159 cons: SEQUENCE 759 | 3:d=1 hl=2 l= 13 cons: SEQUENCE 760 | 5:d=2 hl=2 l= 9 prim: OBJECT:rsaEncryption 761 | 16:d=2 hl=2 l= 0 prim: NULL 762 | 18:d=1 hl=3 l= 141 prim: BIT STRING:RSAPublicKey (below) 763 | 764 | RSAPublicKey ASN1 container 765 | 0:d=0 hl=3 l= 137 cons: SEQUENCE 766 | 3:d=1 hl=3 l= 129 prim: INTEGER:Public modulus 767 | 135:d=1 hl=2 l= 3 prim: INTEGER:Public exponent 768 | */ 769 | 770 | int rsa_parse_public_key( rsa_context *rsa, unsigned char *buf, int buflen ) 771 | { 772 | unsigned char *p, *end; 773 | int ret, len; 774 | 775 | p = buf; 776 | end = buf+buflen; 777 | 778 | if( ( ret = asn1_get_tag( &p, end, &len, 779 | ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) { 780 | return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret ); 781 | } 782 | 783 | if( ( ret = asn1_get_tag( &p, end, &len, 784 | ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) == 0 ) { 785 | /* Skip over embedded rsaEncryption Object */ 786 | p+=len; 787 | 788 | /* The RSAPublicKey ASN1 container is wrapped in a BIT STRING */ 789 | if( ( ret = asn1_get_tag( &p, end, &len, 790 | ASN1_BIT_STRING ) ) != 0 ) { 791 | return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret ); 792 | } 793 | 794 | /* Limit range to that BIT STRING */ 795 | end = p + len; 796 | p++; 797 | 798 | if( ( ret = asn1_get_tag( &p, end, &len, 799 | ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) { 800 | return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret ); 801 | } 802 | } 803 | 804 | if ( ( ( ret = asn1_get_mpi( &p, end, &(rsa->N) ) ) == 0 ) && 805 | ( ( ret = asn1_get_mpi( &p, end, &(rsa->E) ) ) == 0 ) ) { 806 | rsa->len = mpi_size( &rsa->N ); 807 | return 0; 808 | } 809 | 810 | return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret ); 811 | } 812 | 813 | /* 814 | * Parse a private RSA key 815 | */ 816 | int rsa_parse_key( rsa_context *rsa, unsigned char *buf, int buflen, 817 | unsigned char *pwd, int pwdlen ) 818 | { 819 | int ret, len, enc; 820 | unsigned char *s1, *s2; 821 | unsigned char *p, *end; 822 | 823 | s1 = (unsigned char *) strstr( (char *) buf, 824 | "-----BEGIN RSA PRIVATE KEY-----" ); 825 | 826 | if( s1 != NULL ) 827 | { 828 | s2 = (unsigned char *) strstr( (char *) buf, 829 | "-----END RSA PRIVATE KEY-----" ); 830 | 831 | if( s2 == NULL || s2 <= s1 ) 832 | return( POLARSSL_ERR_X509_KEY_INVALID_PEM ); 833 | 834 | s1 += 31; 835 | if( *s1 == '\r' ) s1++; 836 | if( *s1 == '\n' ) s1++; 837 | else return( POLARSSL_ERR_X509_KEY_INVALID_PEM ); 838 | 839 | enc = 0; 840 | 841 | if( memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 ) 842 | { 843 | return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE ); 844 | } 845 | 846 | len = 0; 847 | ret = base64_decode( NULL, &len, s1, s2 - s1 ); 848 | 849 | if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER ) 850 | return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM ); 851 | 852 | if( ( buf = (unsigned char *) malloc( len ) ) == NULL ) 853 | return( 1 ); 854 | 855 | if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 ) 856 | { 857 | free( buf ); 858 | return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM ); 859 | } 860 | 861 | buflen = len; 862 | 863 | if( enc != 0 ) 864 | { 865 | return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE ); 866 | } 867 | } 868 | 869 | memset( rsa, 0, sizeof( rsa_context ) ); 870 | 871 | p = buf; 872 | end = buf + buflen; 873 | 874 | /* 875 | * RSAPrivateKey ::= SEQUENCE { 876 | * version Version, 877 | * modulus INTEGER, -- n 878 | * publicExponent INTEGER, -- e 879 | * privateExponent INTEGER, -- d 880 | * prime1 INTEGER, -- p 881 | * prime2 INTEGER, -- q 882 | * exponent1 INTEGER, -- d mod (p-1) 883 | * exponent2 INTEGER, -- d mod (q-1) 884 | * coefficient INTEGER, -- (inverse of q) mod p 885 | * otherPrimeInfos OtherPrimeInfos OPTIONAL 886 | * } 887 | */ 888 | if( ( ret = asn1_get_tag( &p, end, &len, 889 | ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) 890 | { 891 | if( s1 != NULL ) 892 | free( buf ); 893 | 894 | rsa_free( rsa ); 895 | return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret ); 896 | } 897 | 898 | end = p + len; 899 | 900 | if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 ) 901 | { 902 | if( s1 != NULL ) 903 | free( buf ); 904 | 905 | rsa_free( rsa ); 906 | return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret ); 907 | } 908 | 909 | if( rsa->ver != 0 ) 910 | { 911 | if( s1 != NULL ) 912 | free( buf ); 913 | 914 | rsa_free( rsa ); 915 | return( ret | POLARSSL_ERR_X509_KEY_INVALID_VERSION ); 916 | } 917 | 918 | if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 || 919 | ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 || 920 | ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 || 921 | ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 || 922 | ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 || 923 | ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 || 924 | ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 || 925 | ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 ) 926 | { 927 | if( s1 != NULL ) 928 | free( buf ); 929 | 930 | rsa_free( rsa ); 931 | return( ret | POLARSSL_ERR_X509_KEY_INVALID_FORMAT ); 932 | } 933 | 934 | rsa->len = mpi_size( &rsa->N ); 935 | 936 | if( p != end ) 937 | { 938 | if( s1 != NULL ) 939 | free( buf ); 940 | 941 | rsa_free( rsa ); 942 | return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | 943 | POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); 944 | } 945 | 946 | if( ( ret = rsa_check_privkey( rsa ) ) != 0 ) 947 | { 948 | if( s1 != NULL ) 949 | free( buf ); 950 | 951 | rsa_free( rsa ); 952 | return( ret ); 953 | } 954 | 955 | if( s1 != NULL ) 956 | free( buf ); 957 | 958 | return( 0 ); 959 | } 960 | 961 | -------------------------------------------------------------------------------- /bn_mul.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file bn_mul.h 3 | * 4 | * Copyright (C) 2006-2010, Brainspark B.V. 5 | * 6 | * This file is part of PolarSSL (http://www.polarssl.org) 7 | * Lead Maintainer: Paul Bakker 8 | * 9 | * All rights reserved. 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License along 22 | * with this program; if not, write to the Free Software Foundation, Inc., 23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 24 | */ 25 | /* 26 | * Multiply source vector [s] with b, add result 27 | * to destination vector [d] and set carry c. 28 | * 29 | * Currently supports: 30 | * 31 | * . IA-32 (386+) . AMD64 / EM64T 32 | * . IA-32 (SSE2) . Motorola 68000 33 | * . PowerPC, 32-bit . MicroBlaze 34 | * . PowerPC, 64-bit . TriCore 35 | * . SPARC v8 . ARM v3+ 36 | * . Alpha . MIPS32 37 | * . C, longlong . C, generic 38 | */ 39 | #ifndef POLARSSL_BN_MUL_H 40 | #define POLARSSL_BN_MUL_H 41 | 42 | #if defined(POLARSSL_HAVE_ASM) 43 | 44 | #if defined(__GNUC__) 45 | #if defined(__i386__) 46 | 47 | #define MULADDC_INIT \ 48 | asm( " \ 49 | movl %%ebx, %0; \ 50 | movl %5, %%esi; \ 51 | movl %6, %%edi; \ 52 | movl %7, %%ecx; \ 53 | movl %8, %%ebx; \ 54 | " 55 | 56 | #define MULADDC_CORE \ 57 | " \ 58 | lodsl; \ 59 | mull %%ebx; \ 60 | addl %%ecx, %%eax; \ 61 | adcl $0, %%edx; \ 62 | addl (%%edi), %%eax; \ 63 | adcl $0, %%edx; \ 64 | movl %%edx, %%ecx; \ 65 | stosl; \ 66 | " 67 | 68 | #if defined(POLARSSL_HAVE_SSE2) 69 | 70 | #define MULADDC_HUIT \ 71 | " \ 72 | movd %%ecx, %%mm1; \ 73 | movd %%ebx, %%mm0; \ 74 | movd (%%edi), %%mm3; \ 75 | paddq %%mm3, %%mm1; \ 76 | movd (%%esi), %%mm2; \ 77 | pmuludq %%mm0, %%mm2; \ 78 | movd 4(%%esi), %%mm4; \ 79 | pmuludq %%mm0, %%mm4; \ 80 | movd 8(%%esi), %%mm6; \ 81 | pmuludq %%mm0, %%mm6; \ 82 | movd 12(%%esi), %%mm7; \ 83 | pmuludq %%mm0, %%mm7; \ 84 | paddq %%mm2, %%mm1; \ 85 | movd 4(%%edi), %%mm3; \ 86 | paddq %%mm4, %%mm3; \ 87 | movd 8(%%edi), %%mm5; \ 88 | paddq %%mm6, %%mm5; \ 89 | movd 12(%%edi), %%mm4; \ 90 | paddq %%mm4, %%mm7; \ 91 | movd %%mm1, (%%edi); \ 92 | movd 16(%%esi), %%mm2; \ 93 | pmuludq %%mm0, %%mm2; \ 94 | psrlq $32, %%mm1; \ 95 | movd 20(%%esi), %%mm4; \ 96 | pmuludq %%mm0, %%mm4; \ 97 | paddq %%mm3, %%mm1; \ 98 | movd 24(%%esi), %%mm6; \ 99 | pmuludq %%mm0, %%mm6; \ 100 | movd %%mm1, 4(%%edi); \ 101 | psrlq $32, %%mm1; \ 102 | movd 28(%%esi), %%mm3; \ 103 | pmuludq %%mm0, %%mm3; \ 104 | paddq %%mm5, %%mm1; \ 105 | movd 16(%%edi), %%mm5; \ 106 | paddq %%mm5, %%mm2; \ 107 | movd %%mm1, 8(%%edi); \ 108 | psrlq $32, %%mm1; \ 109 | paddq %%mm7, %%mm1; \ 110 | movd 20(%%edi), %%mm5; \ 111 | paddq %%mm5, %%mm4; \ 112 | movd %%mm1, 12(%%edi); \ 113 | psrlq $32, %%mm1; \ 114 | paddq %%mm2, %%mm1; \ 115 | movd 24(%%edi), %%mm5; \ 116 | paddq %%mm5, %%mm6; \ 117 | movd %%mm1, 16(%%edi); \ 118 | psrlq $32, %%mm1; \ 119 | paddq %%mm4, %%mm1; \ 120 | movd 28(%%edi), %%mm5; \ 121 | paddq %%mm5, %%mm3; \ 122 | movd %%mm1, 20(%%edi); \ 123 | psrlq $32, %%mm1; \ 124 | paddq %%mm6, %%mm1; \ 125 | movd %%mm1, 24(%%edi); \ 126 | psrlq $32, %%mm1; \ 127 | paddq %%mm3, %%mm1; \ 128 | movd %%mm1, 28(%%edi); \ 129 | addl $32, %%edi; \ 130 | addl $32, %%esi; \ 131 | psrlq $32, %%mm1; \ 132 | movd %%mm1, %%ecx; \ 133 | " 134 | 135 | #define MULADDC_STOP \ 136 | " \ 137 | emms; \ 138 | movl %4, %%ebx; \ 139 | movl %%ecx, %1; \ 140 | movl %%edi, %2; \ 141 | movl %%esi, %3; \ 142 | " \ 143 | : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \ 144 | : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \ 145 | : "eax", "ecx", "edx", "esi", "edi" \ 146 | ); 147 | 148 | #else 149 | 150 | #define MULADDC_STOP \ 151 | " \ 152 | movl %4, %%ebx; \ 153 | movl %%ecx, %1; \ 154 | movl %%edi, %2; \ 155 | movl %%esi, %3; \ 156 | " \ 157 | : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \ 158 | : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \ 159 | : "eax", "ecx", "edx", "esi", "edi" \ 160 | ); 161 | #endif /* SSE2 */ 162 | #endif /* i386 */ 163 | 164 | #if defined(__amd64__) || defined (__x86_64__) 165 | 166 | #define MULADDC_INIT \ 167 | asm( "movq %0, %%rsi " :: "m" (s)); \ 168 | asm( "movq %0, %%rdi " :: "m" (d)); \ 169 | asm( "movq %0, %%rcx " :: "m" (c)); \ 170 | asm( "movq %0, %%rbx " :: "m" (b)); \ 171 | asm( "xorq %r8, %r8 " ); 172 | 173 | #define MULADDC_CORE \ 174 | asm( "movq (%rsi),%rax " ); \ 175 | asm( "mulq %rbx " ); \ 176 | asm( "addq $8, %rsi " ); \ 177 | asm( "addq %rcx, %rax " ); \ 178 | asm( "movq %r8, %rcx " ); \ 179 | asm( "adcq $0, %rdx " ); \ 180 | asm( "nop " ); \ 181 | asm( "addq %rax, (%rdi) " ); \ 182 | asm( "adcq %rdx, %rcx " ); \ 183 | asm( "addq $8, %rdi " ); 184 | 185 | #define MULADDC_STOP \ 186 | asm( "movq %%rcx, %0 " : "=m" (c)); \ 187 | asm( "movq %%rdi, %0 " : "=m" (d)); \ 188 | asm( "movq %%rsi, %0 " : "=m" (s) :: \ 189 | "rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8" ); 190 | 191 | #endif /* AMD64 */ 192 | 193 | #if defined(__mc68020__) || defined(__mcpu32__) 194 | 195 | #define MULADDC_INIT \ 196 | asm( "movl %0, %%a2 " :: "m" (s)); \ 197 | asm( "movl %0, %%a3 " :: "m" (d)); \ 198 | asm( "movl %0, %%d3 " :: "m" (c)); \ 199 | asm( "movl %0, %%d2 " :: "m" (b)); \ 200 | asm( "moveq #0, %d0 " ); 201 | 202 | #define MULADDC_CORE \ 203 | asm( "movel %a2@+, %d1 " ); \ 204 | asm( "mulul %d2, %d4:%d1 " ); \ 205 | asm( "addl %d3, %d1 " ); \ 206 | asm( "addxl %d0, %d4 " ); \ 207 | asm( "moveq #0, %d3 " ); \ 208 | asm( "addl %d1, %a3@+ " ); \ 209 | asm( "addxl %d4, %d3 " ); 210 | 211 | #define MULADDC_STOP \ 212 | asm( "movl %%d3, %0 " : "=m" (c)); \ 213 | asm( "movl %%a3, %0 " : "=m" (d)); \ 214 | asm( "movl %%a2, %0 " : "=m" (s) :: \ 215 | "d0", "d1", "d2", "d3", "d4", "a2", "a3" ); 216 | 217 | #define MULADDC_HUIT \ 218 | asm( "movel %a2@+, %d1 " ); \ 219 | asm( "mulul %d2, %d4:%d1 " ); \ 220 | asm( "addxl %d3, %d1 " ); \ 221 | asm( "addxl %d0, %d4 " ); \ 222 | asm( "addl %d1, %a3@+ " ); \ 223 | asm( "movel %a2@+, %d1 " ); \ 224 | asm( "mulul %d2, %d3:%d1 " ); \ 225 | asm( "addxl %d4, %d1 " ); \ 226 | asm( "addxl %d0, %d3 " ); \ 227 | asm( "addl %d1, %a3@+ " ); \ 228 | asm( "movel %a2@+, %d1 " ); \ 229 | asm( "mulul %d2, %d4:%d1 " ); \ 230 | asm( "addxl %d3, %d1 " ); \ 231 | asm( "addxl %d0, %d4 " ); \ 232 | asm( "addl %d1, %a3@+ " ); \ 233 | asm( "movel %a2@+, %d1 " ); \ 234 | asm( "mulul %d2, %d3:%d1 " ); \ 235 | asm( "addxl %d4, %d1 " ); \ 236 | asm( "addxl %d0, %d3 " ); \ 237 | asm( "addl %d1, %a3@+ " ); \ 238 | asm( "movel %a2@+, %d1 " ); \ 239 | asm( "mulul %d2, %d4:%d1 " ); \ 240 | asm( "addxl %d3, %d1 " ); \ 241 | asm( "addxl %d0, %d4 " ); \ 242 | asm( "addl %d1, %a3@+ " ); \ 243 | asm( "movel %a2@+, %d1 " ); \ 244 | asm( "mulul %d2, %d3:%d1 " ); \ 245 | asm( "addxl %d4, %d1 " ); \ 246 | asm( "addxl %d0, %d3 " ); \ 247 | asm( "addl %d1, %a3@+ " ); \ 248 | asm( "movel %a2@+, %d1 " ); \ 249 | asm( "mulul %d2, %d4:%d1 " ); \ 250 | asm( "addxl %d3, %d1 " ); \ 251 | asm( "addxl %d0, %d4 " ); \ 252 | asm( "addl %d1, %a3@+ " ); \ 253 | asm( "movel %a2@+, %d1 " ); \ 254 | asm( "mulul %d2, %d3:%d1 " ); \ 255 | asm( "addxl %d4, %d1 " ); \ 256 | asm( "addxl %d0, %d3 " ); \ 257 | asm( "addl %d1, %a3@+ " ); \ 258 | asm( "addxl %d0, %d3 " ); 259 | 260 | #endif /* MC68000 */ 261 | 262 | #if defined(__powerpc__) || defined(__ppc__) 263 | #if defined(__powerpc64__) || defined(__ppc64__) 264 | 265 | #if defined(__MACH__) && defined(__APPLE__) 266 | 267 | #define MULADDC_INIT \ 268 | asm( "ld r3, %0 " :: "m" (s)); \ 269 | asm( "ld r4, %0 " :: "m" (d)); \ 270 | asm( "ld r5, %0 " :: "m" (c)); \ 271 | asm( "ld r6, %0 " :: "m" (b)); \ 272 | asm( "addi r3, r3, -8 " ); \ 273 | asm( "addi r4, r4, -8 " ); \ 274 | asm( "addic r5, r5, 0 " ); 275 | 276 | #define MULADDC_CORE \ 277 | asm( "ldu r7, 8(r3) " ); \ 278 | asm( "mulld r8, r7, r6 " ); \ 279 | asm( "mulhdu r9, r7, r6 " ); \ 280 | asm( "adde r8, r8, r5 " ); \ 281 | asm( "ld r7, 8(r4) " ); \ 282 | asm( "addze r5, r9 " ); \ 283 | asm( "addc r8, r8, r7 " ); \ 284 | asm( "stdu r8, 8(r4) " ); 285 | 286 | #define MULADDC_STOP \ 287 | asm( "addze r5, r5 " ); \ 288 | asm( "addi r4, r4, 8 " ); \ 289 | asm( "addi r3, r3, 8 " ); \ 290 | asm( "std r5, %0 " : "=m" (c)); \ 291 | asm( "std r4, %0 " : "=m" (d)); \ 292 | asm( "std r3, %0 " : "=m" (s) :: \ 293 | "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); 294 | 295 | #else 296 | 297 | #define MULADDC_INIT \ 298 | asm( "ld %%r3, %0 " :: "m" (s)); \ 299 | asm( "ld %%r4, %0 " :: "m" (d)); \ 300 | asm( "ld %%r5, %0 " :: "m" (c)); \ 301 | asm( "ld %%r6, %0 " :: "m" (b)); \ 302 | asm( "addi %r3, %r3, -8 " ); \ 303 | asm( "addi %r4, %r4, -8 " ); \ 304 | asm( "addic %r5, %r5, 0 " ); 305 | 306 | #define MULADDC_CORE \ 307 | asm( "ldu %r7, 8(%r3) " ); \ 308 | asm( "mulld %r8, %r7, %r6 " ); \ 309 | asm( "mulhdu %r9, %r7, %r6 " ); \ 310 | asm( "adde %r8, %r8, %r5 " ); \ 311 | asm( "ld %r7, 8(%r4) " ); \ 312 | asm( "addze %r5, %r9 " ); \ 313 | asm( "addc %r8, %r8, %r7 " ); \ 314 | asm( "stdu %r8, 8(%r4) " ); 315 | 316 | #define MULADDC_STOP \ 317 | asm( "addze %r5, %r5 " ); \ 318 | asm( "addi %r4, %r4, 8 " ); \ 319 | asm( "addi %r3, %r3, 8 " ); \ 320 | asm( "std %%r5, %0 " : "=m" (c)); \ 321 | asm( "std %%r4, %0 " : "=m" (d)); \ 322 | asm( "std %%r3, %0 " : "=m" (s) :: \ 323 | "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); 324 | 325 | #endif 326 | 327 | #else /* PPC32 */ 328 | 329 | #if defined(__MACH__) && defined(__APPLE__) 330 | 331 | #define MULADDC_INIT \ 332 | asm( "lwz r3, %0 " :: "m" (s)); \ 333 | asm( "lwz r4, %0 " :: "m" (d)); \ 334 | asm( "lwz r5, %0 " :: "m" (c)); \ 335 | asm( "lwz r6, %0 " :: "m" (b)); \ 336 | asm( "addi r3, r3, -4 " ); \ 337 | asm( "addi r4, r4, -4 " ); \ 338 | asm( "addic r5, r5, 0 " ); 339 | 340 | #define MULADDC_CORE \ 341 | asm( "lwzu r7, 4(r3) " ); \ 342 | asm( "mullw r8, r7, r6 " ); \ 343 | asm( "mulhwu r9, r7, r6 " ); \ 344 | asm( "adde r8, r8, r5 " ); \ 345 | asm( "lwz r7, 4(r4) " ); \ 346 | asm( "addze r5, r9 " ); \ 347 | asm( "addc r8, r8, r7 " ); \ 348 | asm( "stwu r8, 4(r4) " ); 349 | 350 | #define MULADDC_STOP \ 351 | asm( "addze r5, r5 " ); \ 352 | asm( "addi r4, r4, 4 " ); \ 353 | asm( "addi r3, r3, 4 " ); \ 354 | asm( "stw r5, %0 " : "=m" (c)); \ 355 | asm( "stw r4, %0 " : "=m" (d)); \ 356 | asm( "stw r3, %0 " : "=m" (s) :: \ 357 | "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); 358 | 359 | #else 360 | 361 | #define MULADDC_INIT \ 362 | asm( "lwz %%r3, %0 " :: "m" (s)); \ 363 | asm( "lwz %%r4, %0 " :: "m" (d)); \ 364 | asm( "lwz %%r5, %0 " :: "m" (c)); \ 365 | asm( "lwz %%r6, %0 " :: "m" (b)); \ 366 | asm( "addi %r3, %r3, -4 " ); \ 367 | asm( "addi %r4, %r4, -4 " ); \ 368 | asm( "addic %r5, %r5, 0 " ); 369 | 370 | #define MULADDC_CORE \ 371 | asm( "lwzu %r7, 4(%r3) " ); \ 372 | asm( "mullw %r8, %r7, %r6 " ); \ 373 | asm( "mulhwu %r9, %r7, %r6 " ); \ 374 | asm( "adde %r8, %r8, %r5 " ); \ 375 | asm( "lwz %r7, 4(%r4) " ); \ 376 | asm( "addze %r5, %r9 " ); \ 377 | asm( "addc %r8, %r8, %r7 " ); \ 378 | asm( "stwu %r8, 4(%r4) " ); 379 | 380 | #define MULADDC_STOP \ 381 | asm( "addze %r5, %r5 " ); \ 382 | asm( "addi %r4, %r4, 4 " ); \ 383 | asm( "addi %r3, %r3, 4 " ); \ 384 | asm( "stw %%r5, %0 " : "=m" (c)); \ 385 | asm( "stw %%r4, %0 " : "=m" (d)); \ 386 | asm( "stw %%r3, %0 " : "=m" (s) :: \ 387 | "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); 388 | 389 | #endif 390 | 391 | #endif /* PPC32 */ 392 | #endif /* PPC64 */ 393 | 394 | #if defined(__sparc__) 395 | 396 | #define MULADDC_INIT \ 397 | asm( "ld %0, %%o0 " :: "m" (s)); \ 398 | asm( "ld %0, %%o1 " :: "m" (d)); \ 399 | asm( "ld %0, %%o2 " :: "m" (c)); \ 400 | asm( "ld %0, %%o3 " :: "m" (b)); 401 | 402 | #define MULADDC_CORE \ 403 | asm( "ld [%o0], %o4 " ); \ 404 | asm( "inc 4, %o0 " ); \ 405 | asm( "ld [%o1], %o5 " ); \ 406 | asm( "umul %o3, %o4, %o4 " ); \ 407 | asm( "addcc %o4, %o2, %o4 " ); \ 408 | asm( "rd %y, %g1 " ); \ 409 | asm( "addx %g1, 0, %g1 " ); \ 410 | asm( "addcc %o4, %o5, %o4 " ); \ 411 | asm( "st %o4, [%o1] " ); \ 412 | asm( "addx %g1, 0, %o2 " ); \ 413 | asm( "inc 4, %o1 " ); 414 | 415 | #define MULADDC_STOP \ 416 | asm( "st %%o2, %0 " : "=m" (c)); \ 417 | asm( "st %%o1, %0 " : "=m" (d)); \ 418 | asm( "st %%o0, %0 " : "=m" (s) :: \ 419 | "g1", "o0", "o1", "o2", "o3", "o4", "o5" ); 420 | 421 | #endif /* SPARCv8 */ 422 | 423 | #if defined(__microblaze__) || defined(microblaze) 424 | 425 | #define MULADDC_INIT \ 426 | asm( "lwi r3, %0 " :: "m" (s)); \ 427 | asm( "lwi r4, %0 " :: "m" (d)); \ 428 | asm( "lwi r5, %0 " :: "m" (c)); \ 429 | asm( "lwi r6, %0 " :: "m" (b)); \ 430 | asm( "andi r7, r6, 0xffff" ); \ 431 | asm( "bsrli r6, r6, 16 " ); 432 | 433 | #define MULADDC_CORE \ 434 | asm( "lhui r8, r3, 0 " ); \ 435 | asm( "addi r3, r3, 2 " ); \ 436 | asm( "lhui r9, r3, 0 " ); \ 437 | asm( "addi r3, r3, 2 " ); \ 438 | asm( "mul r10, r9, r6 " ); \ 439 | asm( "mul r11, r8, r7 " ); \ 440 | asm( "mul r12, r9, r7 " ); \ 441 | asm( "mul r13, r8, r6 " ); \ 442 | asm( "bsrli r8, r10, 16 " ); \ 443 | asm( "bsrli r9, r11, 16 " ); \ 444 | asm( "add r13, r13, r8 " ); \ 445 | asm( "add r13, r13, r9 " ); \ 446 | asm( "bslli r10, r10, 16 " ); \ 447 | asm( "bslli r11, r11, 16 " ); \ 448 | asm( "add r12, r12, r10 " ); \ 449 | asm( "addc r13, r13, r0 " ); \ 450 | asm( "add r12, r12, r11 " ); \ 451 | asm( "addc r13, r13, r0 " ); \ 452 | asm( "lwi r10, r4, 0 " ); \ 453 | asm( "add r12, r12, r10 " ); \ 454 | asm( "addc r13, r13, r0 " ); \ 455 | asm( "add r12, r12, r5 " ); \ 456 | asm( "addc r5, r13, r0 " ); \ 457 | asm( "swi r12, r4, 0 " ); \ 458 | asm( "addi r4, r4, 4 " ); 459 | 460 | #define MULADDC_STOP \ 461 | asm( "swi r5, %0 " : "=m" (c)); \ 462 | asm( "swi r4, %0 " : "=m" (d)); \ 463 | asm( "swi r3, %0 " : "=m" (s) :: \ 464 | "r3", "r4" , "r5" , "r6" , "r7" , "r8" , \ 465 | "r9", "r10", "r11", "r12", "r13" ); 466 | 467 | #endif /* MicroBlaze */ 468 | 469 | #if defined(__tricore__) 470 | 471 | #define MULADDC_INIT \ 472 | asm( "ld.a %%a2, %0 " :: "m" (s)); \ 473 | asm( "ld.a %%a3, %0 " :: "m" (d)); \ 474 | asm( "ld.w %%d4, %0 " :: "m" (c)); \ 475 | asm( "ld.w %%d1, %0 " :: "m" (b)); \ 476 | asm( "xor %d5, %d5 " ); 477 | 478 | #define MULADDC_CORE \ 479 | asm( "ld.w %d0, [%a2+] " ); \ 480 | asm( "madd.u %e2, %e4, %d0, %d1 " ); \ 481 | asm( "ld.w %d0, [%a3] " ); \ 482 | asm( "addx %d2, %d2, %d0 " ); \ 483 | asm( "addc %d3, %d3, 0 " ); \ 484 | asm( "mov %d4, %d3 " ); \ 485 | asm( "st.w [%a3+], %d2 " ); 486 | 487 | #define MULADDC_STOP \ 488 | asm( "st.w %0, %%d4 " : "=m" (c)); \ 489 | asm( "st.a %0, %%a3 " : "=m" (d)); \ 490 | asm( "st.a %0, %%a2 " : "=m" (s) :: \ 491 | "d0", "d1", "e2", "d4", "a2", "a3" ); 492 | 493 | #endif /* TriCore */ 494 | 495 | #if defined(__arm__) 496 | 497 | #define MULADDC_INIT \ 498 | asm( "ldr r0, %0 " :: "m" (s)); \ 499 | asm( "ldr r1, %0 " :: "m" (d)); \ 500 | asm( "ldr r2, %0 " :: "m" (c)); \ 501 | asm( "ldr r3, %0 " :: "m" (b)); 502 | 503 | #define MULADDC_CORE \ 504 | asm( "ldr r4, [r0], #4 " ); \ 505 | asm( "mov r5, #0 " ); \ 506 | asm( "ldr r6, [r1] " ); \ 507 | asm( "umlal r2, r5, r3, r4 " ); \ 508 | asm( "adds r7, r6, r2 " ); \ 509 | asm( "adc r2, r5, #0 " ); \ 510 | asm( "str r7, [r1], #4 " ); 511 | 512 | #define MULADDC_STOP \ 513 | asm( "str r2, %0 " : "=m" (c)); \ 514 | asm( "str r1, %0 " : "=m" (d)); \ 515 | asm( "str r0, %0 " : "=m" (s) :: \ 516 | "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" ); 517 | 518 | #endif /* ARMv3 */ 519 | 520 | #if defined(__alpha__) 521 | 522 | #define MULADDC_INIT \ 523 | asm( "ldq $1, %0 " :: "m" (s)); \ 524 | asm( "ldq $2, %0 " :: "m" (d)); \ 525 | asm( "ldq $3, %0 " :: "m" (c)); \ 526 | asm( "ldq $4, %0 " :: "m" (b)); 527 | 528 | #define MULADDC_CORE \ 529 | asm( "ldq $6, 0($1) " ); \ 530 | asm( "addq $1, 8, $1 " ); \ 531 | asm( "mulq $6, $4, $7 " ); \ 532 | asm( "umulh $6, $4, $6 " ); \ 533 | asm( "addq $7, $3, $7 " ); \ 534 | asm( "cmpult $7, $3, $3 " ); \ 535 | asm( "ldq $5, 0($2) " ); \ 536 | asm( "addq $7, $5, $7 " ); \ 537 | asm( "cmpult $7, $5, $5 " ); \ 538 | asm( "stq $7, 0($2) " ); \ 539 | asm( "addq $2, 8, $2 " ); \ 540 | asm( "addq $6, $3, $3 " ); \ 541 | asm( "addq $5, $3, $3 " ); 542 | 543 | #define MULADDC_STOP \ 544 | asm( "stq $3, %0 " : "=m" (c)); \ 545 | asm( "stq $2, %0 " : "=m" (d)); \ 546 | asm( "stq $1, %0 " : "=m" (s) :: \ 547 | "$1", "$2", "$3", "$4", "$5", "$6", "$7" ); 548 | 549 | #endif /* Alpha */ 550 | 551 | #if defined(__mips__) 552 | 553 | #define MULADDC_INIT \ 554 | asm( "lw $10, %0 " :: "m" (s)); \ 555 | asm( "lw $11, %0 " :: "m" (d)); \ 556 | asm( "lw $12, %0 " :: "m" (c)); \ 557 | asm( "lw $13, %0 " :: "m" (b)); 558 | 559 | #define MULADDC_CORE \ 560 | asm( "lw $14, 0($10) " ); \ 561 | asm( "multu $13, $14 " ); \ 562 | asm( "addi $10, $10, 4 " ); \ 563 | asm( "mflo $14 " ); \ 564 | asm( "mfhi $9 " ); \ 565 | asm( "addu $14, $12, $14 " ); \ 566 | asm( "lw $15, 0($11) " ); \ 567 | asm( "sltu $12, $14, $12 " ); \ 568 | asm( "addu $15, $14, $15 " ); \ 569 | asm( "sltu $14, $15, $14 " ); \ 570 | asm( "addu $12, $12, $9 " ); \ 571 | asm( "sw $15, 0($11) " ); \ 572 | asm( "addu $12, $12, $14 " ); \ 573 | asm( "addi $11, $11, 4 " ); 574 | 575 | #define MULADDC_STOP \ 576 | asm( "sw $12, %0 " : "=m" (c)); \ 577 | asm( "sw $11, %0 " : "=m" (d)); \ 578 | asm( "sw $10, %0 " : "=m" (s) :: \ 579 | "$9", "$10", "$11", "$12", "$13", "$14", "$15" ); 580 | 581 | #endif /* MIPS */ 582 | #endif /* GNUC */ 583 | 584 | #if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__) 585 | 586 | #define MULADDC_INIT \ 587 | __asm mov esi, s \ 588 | __asm mov edi, d \ 589 | __asm mov ecx, c \ 590 | __asm mov ebx, b 591 | 592 | #define MULADDC_CORE \ 593 | __asm lodsd \ 594 | __asm mul ebx \ 595 | __asm add eax, ecx \ 596 | __asm adc edx, 0 \ 597 | __asm add eax, [edi] \ 598 | __asm adc edx, 0 \ 599 | __asm mov ecx, edx \ 600 | __asm stosd 601 | 602 | #if defined(POLARSSL_HAVE_SSE2) 603 | 604 | #define EMIT __asm _emit 605 | 606 | #define MULADDC_HUIT \ 607 | EMIT 0x0F EMIT 0x6E EMIT 0xC9 \ 608 | EMIT 0x0F EMIT 0x6E EMIT 0xC3 \ 609 | EMIT 0x0F EMIT 0x6E EMIT 0x1F \ 610 | EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ 611 | EMIT 0x0F EMIT 0x6E EMIT 0x16 \ 612 | EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \ 613 | EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x04 \ 614 | EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \ 615 | EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x08 \ 616 | EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \ 617 | EMIT 0x0F EMIT 0x6E EMIT 0x7E EMIT 0x0C \ 618 | EMIT 0x0F EMIT 0xF4 EMIT 0xF8 \ 619 | EMIT 0x0F EMIT 0xD4 EMIT 0xCA \ 620 | EMIT 0x0F EMIT 0x6E EMIT 0x5F EMIT 0x04 \ 621 | EMIT 0x0F EMIT 0xD4 EMIT 0xDC \ 622 | EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x08 \ 623 | EMIT 0x0F EMIT 0xD4 EMIT 0xEE \ 624 | EMIT 0x0F EMIT 0x6E EMIT 0x67 EMIT 0x0C \ 625 | EMIT 0x0F EMIT 0xD4 EMIT 0xFC \ 626 | EMIT 0x0F EMIT 0x7E EMIT 0x0F \ 627 | EMIT 0x0F EMIT 0x6E EMIT 0x56 EMIT 0x10 \ 628 | EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \ 629 | EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ 630 | EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x14 \ 631 | EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \ 632 | EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ 633 | EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x18 \ 634 | EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \ 635 | EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x04 \ 636 | EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ 637 | EMIT 0x0F EMIT 0x6E EMIT 0x5E EMIT 0x1C \ 638 | EMIT 0x0F EMIT 0xF4 EMIT 0xD8 \ 639 | EMIT 0x0F EMIT 0xD4 EMIT 0xCD \ 640 | EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x10 \ 641 | EMIT 0x0F EMIT 0xD4 EMIT 0xD5 \ 642 | EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x08 \ 643 | EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ 644 | EMIT 0x0F EMIT 0xD4 EMIT 0xCF \ 645 | EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x14 \ 646 | EMIT 0x0F EMIT 0xD4 EMIT 0xE5 \ 647 | EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x0C \ 648 | EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ 649 | EMIT 0x0F EMIT 0xD4 EMIT 0xCA \ 650 | EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x18 \ 651 | EMIT 0x0F EMIT 0xD4 EMIT 0xF5 \ 652 | EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x10 \ 653 | EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ 654 | EMIT 0x0F EMIT 0xD4 EMIT 0xCC \ 655 | EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x1C \ 656 | EMIT 0x0F EMIT 0xD4 EMIT 0xDD \ 657 | EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x14 \ 658 | EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ 659 | EMIT 0x0F EMIT 0xD4 EMIT 0xCE \ 660 | EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x18 \ 661 | EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ 662 | EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ 663 | EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x1C \ 664 | EMIT 0x83 EMIT 0xC7 EMIT 0x20 \ 665 | EMIT 0x83 EMIT 0xC6 EMIT 0x20 \ 666 | EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ 667 | EMIT 0x0F EMIT 0x7E EMIT 0xC9 668 | 669 | #define MULADDC_STOP \ 670 | EMIT 0x0F EMIT 0x77 \ 671 | __asm mov c, ecx \ 672 | __asm mov d, edi \ 673 | __asm mov s, esi \ 674 | 675 | #else 676 | 677 | #define MULADDC_STOP \ 678 | __asm mov c, ecx \ 679 | __asm mov d, edi \ 680 | __asm mov s, esi \ 681 | 682 | #endif /* SSE2 */ 683 | #endif /* MSVC */ 684 | 685 | #endif /* POLARSSL_HAVE_ASM */ 686 | 687 | #if !defined(MULADDC_CORE) 688 | #if defined(POLARSSL_HAVE_LONGLONG) 689 | 690 | #define MULADDC_INIT \ 691 | { \ 692 | t_dbl r; \ 693 | t_int r0, r1; 694 | 695 | #define MULADDC_CORE \ 696 | r = *(s++) * (t_dbl) b; \ 697 | r0 = r; \ 698 | r1 = r >> biL; \ 699 | r0 += c; r1 += (r0 < c); \ 700 | r0 += *d; r1 += (r0 < *d); \ 701 | c = r1; *(d++) = r0; 702 | 703 | #define MULADDC_STOP \ 704 | } 705 | 706 | #else 707 | #define MULADDC_INIT \ 708 | { \ 709 | t_int s0, s1, b0, b1; \ 710 | t_int r0, r1, rx, ry; \ 711 | b0 = ( b << biH ) >> biH; \ 712 | b1 = ( b >> biH ); 713 | 714 | #define MULADDC_CORE \ 715 | s0 = ( *s << biH ) >> biH; \ 716 | s1 = ( *s >> biH ); s++; \ 717 | rx = s0 * b1; r0 = s0 * b0; \ 718 | ry = s1 * b0; r1 = s1 * b1; \ 719 | r1 += ( rx >> biH ); \ 720 | r1 += ( ry >> biH ); \ 721 | rx <<= biH; ry <<= biH; \ 722 | r0 += rx; r1 += (r0 < rx); \ 723 | r0 += ry; r1 += (r0 < ry); \ 724 | r0 += c; r1 += (r0 < c); \ 725 | r0 += *d; r1 += (r0 < *d); \ 726 | c = r1; *(d++) = r0; 727 | 728 | #define MULADDC_STOP \ 729 | } 730 | 731 | #endif /* C (generic) */ 732 | #endif /* C (longlong) */ 733 | 734 | #endif /* bn_mul.h */ 735 | --------------------------------------------------------------------------------